Heavy Kaffe I/O at startup

Archie Cobbs archie at whistle.com
Thu Oct 15 18:36:44 PDT 1998


Archie Cobbs writes:
> Victor Zandy writes:
> >     Kaffe 1.0b2 generates a lot of very small reads when it starts on
> > my platform, Sparc Solaris 2.5.1.  I have counted nearly 10K calls to
> > read, most between 2 and 4 bytes, when Klasses.jar is read during
> > startup.  Some sequences of 20 of these, maybe longer, are contiguous.
> > 
> >     Does anyone know what this happens?  Why not read the .jar all at
> > once once?  Why not mmap it?  Why not at least read contiguous blocks
> > in one read?
> 
> Yes, I've noticed this too, but haven't looked into it.
> 
> Probably what needs to happen is that somewhere a bunch of I/O
> is being done via read(), write(), lseek(), etc. and it needs
> to be done via fread(), fwrite(), fseek(), etc. instead.

Victor,
Could you try the patch below and see if it helps your startup times.
If no one sees any problems with it, I'll commit it.

Thanks,
-Archie

___________________________________________________________________________
Archie Cobbs   *   Whistle Communications, Inc.  *   http://www.whistle.com

Index: jar.c
===================================================================
RCS file: /cvs/mod/net/kaffe/kaffe/kaffevm/jar.c,v
retrieving revision 1.1.1.1.4.4
diff -u -u -r1.1.1.1.4.4 jar.c
--- jar.c	1998/08/20 23:01:44	1.1.1.1.4.4
+++ jar.c	1998/10/16 01:36:22
@@ -34,10 +34,10 @@
 readCentralDirRecord(jarFile* file)
 {
 	INITREADS();
+	INITSEEK();
 	jarCentralDirectoryRecord head;
 	jarEntry* ret;
 	int len, extra;
-	off_t pos;
 
 	head.signature = READ32(file->fp);
 	head.versionMade = READ16(file->fp);
@@ -79,14 +79,14 @@
 	dprintf("Central record filename: %s\n", ret->fileName);	)
 
 	/* Compute file data location using local header info */
-	pos = lseek(file->fp, (off_t)0, SEEK_CUR);
-	(void)lseek(file->fp, (off_t)(head.relativeLocalHeaderOffset + 28), SEEK_SET);
+	GETPOSITION(file->fp);
+	SEEKTO(file->fp, head.relativeLocalHeaderOffset + 28, SEEK_SET);
 	extra = READ16(file->fp);
 	ret->dataPos = head.relativeLocalHeaderOffset
 		+ SIZEOFLOCALHEADER + head.fileNameLength + extra;
 
 	/* Jump back to original central directory position */
-	(void)lseek(file->fp, pos, SEEK_SET);
+	PUTPOSITION(file->fp);
 	return (ret);
 }
 
@@ -104,7 +104,7 @@
 	uint16 sz;
 	uint32 off;
 
-	if (lseek(file->fp, -SIZEOFCENTRALEND, SEEK_END) == -1) {
+	if (SEEKTO(file->fp, -SIZEOFCENTRALEND, SEEK_END) == -1) {
 		file->error = "Failed to seek into JAR file";
 		return (0);
 	}
@@ -122,7 +122,7 @@
 	ign = READ32(file->fp);	/* Size of central directory */
 	off = READ32(file->fp);	/* Offset of central directory */
 
-	if (lseek(file->fp, (off_t)off, SEEK_SET) == -1) {
+	if (SEEKTO(file->fp, off, SEEK_SET) == -1) {
 		file->error = "Failed to seek into central directory offset";
 		return (0);
 	}
@@ -139,8 +139,8 @@
 
 	file = gc_malloc_fixed(sizeof(jarFile));
 
-	file->fp = open(name, O_RDONLY, 0);
-	if (file->fp == -1) {
+	file->fp = fopen(name, "r");
+	if (file->fp == NULL) {
 		return (0);
 	}
 
@@ -179,12 +179,12 @@
 	uint8* buf;
 	uint8* nbuf;
 
-	if (lseek(file->fp, (off_t)entry->dataPos, SEEK_SET) == -1) {
+	if (SEEKTO(file->fp, entry->dataPos, SEEK_SET) == -1) {
 		file->error = "Failed to seek into JAR file";
 		return (0);
 	}
 	buf = gc_malloc_fixed(entry->compressedSize);
-	if (read(file->fp, buf, entry->compressedSize) != entry->compressedSize) {
+	if (READBYTES(file->fp, entry->compressedSize, buf) != entry->compressedSize) {
 		file->error = "Failed to read from JAR file";
 		gc_free_fixed(buf);
 		return (0);
@@ -232,7 +232,7 @@
 		gc_free_fixed(curr);
 	}
 
-	close(file->fp);
+	fclose(file->fp);
 
 	gc_free_fixed(file);
 }
Index: jar.h
===================================================================
RCS file: /cvs/mod/net/kaffe/kaffe/kaffevm/jar.h,v
retrieving revision 1.1.1.1
diff -u -u -r1.1.1.1 jar.h
--- jar.h	1998/07/10 23:00:37	1.1.1.1
+++ jar.h	1998/10/16 01:36:22
@@ -76,7 +76,7 @@
 
 typedef struct _jarFile {
 
-	int			fp;
+	FILE*			fp;
 	int			count;
 	jarEntry*		head;
 	char*			error;
@@ -113,21 +113,27 @@
  * Macros to read little-endian values.
  */
 #define	INITREADS()		int rtmp; unsigned char rbuf[4]
-#define	READ8(F)		(rtmp = read(F, rbuf, 1), 		    \
-				 rtmp < 1 ? EOF : (unsigned)rbuf[0])
+#define	READ8(F)		(rtmp = fread(rbuf, 1, 1, (F)),		    \
+				 rtmp != 1 ? EOF : (unsigned)rbuf[0])
 
-#define	READ16(F)		(rtmp = read(F, rbuf, 2), 		    \
-				 rtmp < 2 ? EOF : (unsigned)rbuf[0] | 	    \
+#define	READ16(F)		(rtmp = fread(rbuf, 2, 1, (F)),		    \
+				 rtmp != 1 ? EOF : (unsigned)rbuf[0] | 	    \
 						 ((unsigned)rbuf[1]) << 8)
 
-#define	READ32(F)		(rtmp = read(F, rbuf, 4), 		    \
-				 rtmp < 4 ? EOF : (unsigned)rbuf[0] | 	    \
+#define	READ32(F)		(rtmp = fread(rbuf, 4, 1, (F)),		    \
+				 rtmp != 1 ? EOF : (unsigned)rbuf[0] | 	    \
 						 ((unsigned)rbuf[1]) << 8 |\
 						 ((unsigned)rbuf[2]) << 16|\
 						 ((unsigned)rbuf[3]) << 24)
 
-#define	READBYTES(F,S,B)	read(F, B, S)
-#define	SKIPBYTES(F,S)		lseek((F), (long)(S), SEEK_CUR)
+#define	INITSEEK()		fpos_t pos
+#define	SEEKTO(F,S,W)		fseek((F), (long)(S), (W))
+
+#define	GETPOSITION(F)		fgetpos((F), &pos)
+#define	PUTPOSITION(F)		fsetpos((F), &pos)
+
+#define	READBYTES(F,S,B)	fread((B), 1, (S), (F))
+#define	SKIPBYTES(F,S)		SEEKTO((F),(S),SEEK_CUR)
 
 /*
  * Interface.


More information about the kaffe mailing list