--- ray/src/hd/holofile.c 1999/01/07 22:04:49 3.32 +++ ray/src/hd/holofile.c 1999/03/09 08:40:11 3.39 @@ -13,8 +13,12 @@ static char SCCSid[] = "$SunId$ SGI"; #include "holo.h" #ifndef CACHESIZE -#define CACHESIZE 16 /* default cache size (Mbytes, 0==inf) */ +#ifdef BIGMEM +#define CACHESIZE 17 /* default cache size (Mbytes, 0==inf) */ +#else +#define CACHESIZE 5 #endif +#endif #ifndef FREEBEAMS #define FREEBEAMS 1500 /* maximum beams to free at a time */ #endif @@ -26,7 +30,7 @@ static char SCCSid[] = "$SunId$ SGI"; #endif #ifndef FF_DEFAULT /* when to free a beam fragment */ -#define FF_DEFAULT (FF_ALLOC|FF_WRITE|FF_KILL) +#define FF_DEFAULT (FF_WRITE|FF_KILL) #endif #ifndef MINDIRSEL /* minimum directory seek length */ @@ -187,7 +191,7 @@ memerr: } -markdirty(hp, i) /* mark holodeck directory position dirty */ +hdmarkdirty(hp, i) /* mark holodeck directory position dirty */ register HOLO *hp; int i; { @@ -199,7 +203,7 @@ int i; if (lseek(hp->fd, biglob(hp)->fo+(i-1)*sizeof(BEAMI), 0) < 0 || write(hp->fd, (char *)&smudge, sizeof(BEAMI)) != sizeof(BEAMI)) - error(SYSTEM, "seek/write error in markdirty"); + error(SYSTEM, "seek/write error in hdmarkdirty"); hp->dirseg[0].s = i; hp->dirseg[0].n = 1; return; @@ -483,6 +487,7 @@ int (*bf)(); /* callback function (optional) */ } +int hdfreefrag(hp, i) /* free a file fragment */ HOLO *hp; int i; @@ -492,7 +497,7 @@ int i; register int j, k; if (bi->nrd <= 0) - return; + return(0); DCHECK(hp->fd < 0 | hp->fd >= nhdfragls || !hdfragl[hp->fd].nlinks, CONSISTENCY, "bad file descriptor in hdfreefrag"); f = &hdfragl[hp->fd]; @@ -512,7 +517,7 @@ int i; if (j >= MAXFRAGB*FRAGBLK) { f->nfrags = j--; /* stop list growth */ if (bi->nrd <= f->fi[j].nrd) - return; /* new one no better than discard */ + return(0); /* new one no better than discard */ } #endif if (j % FRAGBLK == 0) { /* more (or less) free list space */ @@ -524,7 +529,7 @@ int i; (j+FRAGBLK)*sizeof(BEAMI)); if (newp == NULL) { f->nfrags--; /* graceful failure */ - return; + return(0); } f->fi = newp; } @@ -553,7 +558,9 @@ int i; } biglob(hp)->nrd -= bi->nrd; /* tell fragment it's free */ bi->nrd = 0; - bi->fo = 0; + bi->fo = 0L; + hdmarkdirty(hp, i); /* assume we'll reallocate */ + return(1); } @@ -587,7 +594,7 @@ int fd; unsigned int4 nrays; { register struct fraglist *f; - register int j, k; + register int j; long nfo; if (nrays == 0) @@ -595,19 +602,16 @@ unsigned int4 nrays; DCHECK(fd < 0 | fd >= nhdfragls || !hdfragl[fd].nlinks, CONSISTENCY, "bad file descriptor in hdallocfrag"); f = &hdfragl[fd]; - k = -1; /* find closest-sized fragment */ - for (j = f->nfrags; j-- > 0; ) - if (f->fi[j].nrd >= nrays && - (k < 0 || f->fi[j].nrd < f->fi[k].nrd)) - if (f->fi[k=j].nrd == nrays) - break; - if (k < 0) { /* no fragment -- extend file */ + for (j = f->nfrags; j-- > 0; ) /* first fit algorithm */ + if (f->fi[j].nrd >= nrays) + break; + if (j < 0) { /* no fragment -- extend file */ nfo = f->flen; f->flen += nrays*sizeof(RAYVAL); } else { /* else use fragment */ - nfo = f->fi[k].fo; - f->fi[k].fo += nrays*sizeof(RAYVAL); - f->fi[k].nrd -= nrays; + nfo = f->fi[j].fo; + f->fi[j].fo += nrays*sizeof(RAYVAL); + f->fi[j].nrd -= nrays; } return(nfo); } @@ -618,6 +622,7 @@ hdsyncbeam(hp, i) /* sync beam in memory with beam on register HOLO *hp; register int i; { + int fragfreed; unsigned int4 nrays; unsigned int n; long nfo; @@ -629,8 +634,8 @@ register int i; /* is current fragment OK? */ if (hp->bl[i] == NULL || (nrays = hp->bl[i]->nrm) == hp->bi[i].nrd) return(0); - if (hdfragflags&FF_WRITE && hp->bi[i].nrd) - hdfreefrag(hp, i); /* relinquish old fragment */ + /* relinquish old fragment? */ + fragfreed = hdfragflags&FF_WRITE && hp->bi[i].nrd && hdfreefrag(hp,i); if (nrays) { /* get and write new fragment */ nfo = hdallocfrag(hp->fd, nrays); errno = 0; @@ -645,8 +650,10 @@ register int i; hp->bi[i].fo = nfo; } else hp->bi[i].fo = 0L; - biglob(hp)->nrd += hp->bi[i].nrd = nrays; - markdirty(hp, i); /* section directory now out of date */ + biglob(hp)->nrd += nrays - hp->bi[i].nrd; + hp->bi[i].nrd = nrays; + if (!fragfreed) + hdmarkdirty(hp, i); /* need to flag dir. ent. */ return(1); } @@ -667,10 +674,14 @@ register int i; if (hdfragl[hp->fd].writerr) /* check for file error */ return(0); if (i == 0) { /* clear entire holodeck */ + if (blglob(hp)->nrm == 0) + return(0); /* already clear */ nchanged = 0; for (i = nbeams(hp); i > 0; i--) if (hp->bl[i] != NULL) nchanged += hdfreebeam(hp, i); + DCHECK(blglob(hp)->nrm != 0, + CONSISTENCY, "bad beam count in hdfreebeam"); return(nchanged); } DCHECK(i < 1 | i > nbeams(hp), @@ -702,7 +713,10 @@ register int i; return(nchanged); } if (i == 0) { /* clobber entire holodeck */ + if (biglob(hp)->nrd == 0 & blglob(hp)->nrm == 0) + return(0); /* already empty */ nchanged = 0; + nchanged = 0; for (i = nbeams(hp); i > 0; i--) if (hp->bi[i].nrd > 0 || hp->bl[i] != NULL) nchanged += hdkillbeam(hp, i); @@ -715,15 +729,15 @@ register int i; if (hp->bl[i] != NULL) { /* free memory */ blglob(hp)->nrm -= nchanged = hp->bl[i]->nrm; free((char *)hp->bl[i]); + hp->bl[i] = NULL; } else nchanged = hp->bi[i].nrd; - if (hp->bi[i].nrd) { - if (hdfragflags&FF_KILL) - hdfreefrag(hp, i); - hp->bi[i].nrd = 0; /* make sure it's gone */ + if (hp->bi[i].nrd && !(hdfragflags&FF_KILL && hdfreefrag(hp,i))) { + biglob(hp)->nrd -= hp->bi[i].nrd; /* free failed */ + hp->bi[i].nrd = 0; hp->bi[i].fo = 0L; + hdmarkdirty(hp, i); } - hp->bl[i] = NULL; return(nchanged); } @@ -817,8 +831,7 @@ register HOLO *hp; /* NULL means clean up all */ return; } /* flush all data and free memory */ - hdfreebeam(hp, 0); - hdsync(hp, 0); + hdflush(hp); /* release fragment resources */ hdrelease(hp->fd); /* remove hp from active list */