--- ray/src/hd/rhoptimize.c 1998/11/04 16:37:19 3.1 +++ ray/src/hd/rhoptimize.c 1998/11/12 15:07:49 3.5 @@ -12,13 +12,17 @@ static char SCCSid[] = "$SunId$ SGI"; #include "holo.h" +#include + #ifndef BKBSIZE -#define BKBSIZE 64 /* beam clump size (kilobytes) */ +#define BKBSIZE 256 /* beam clump size (kilobytes) */ #endif - char *progname; +char tempfile[128]; +extern char *rindex(); +extern int quit(); extern long rhinitcopy(); @@ -26,7 +30,6 @@ main(argc, argv) int argc; char *argv[]; { - char nambuf[128]; char *inpname, *outname; int hdfd[2]; long nextipos, lastopos, thisopos; @@ -39,14 +42,18 @@ char *argv[]; inpname = argv[1]; if (argc == 3) /* use given output file */ outname = argv[2]; - else { /* else create temporary file */ - strcpy(nambuf, inpname); - if ((outname = strrchr(nambuf, '/')) != NULL) + else { /* else use temporary file */ + if (access(inpname, R_OK|W_OK) < 0) { /* check permissions */ + sprintf(errmsg, "cannot access \"%s\"", inpname); + error(SYSTEM, errmsg); + } + strcpy(tempfile, inpname); + if ((outname = rindex(tempfile, '/')) != NULL) outname++; else - outname = nambuf; + outname = tempfile; sprintf(outname, "rho%d.hdk", getpid()); - outname = nambuf; + outname = tempfile; } /* copy holodeck file header */ nextipos = rhinitcopy(hdfd, inpname, outname); @@ -71,7 +78,7 @@ char *argv[]; /* clean up */ close(hdfd[0]); close(hdfd[1]); - if (argc == 2 && rename(outname, inpname) < 0) { + if (outname == tempfile && rename(outname, inpname) < 0) { sprintf(errmsg, "cannot rename \"%s\" to \"%s\"", outname, inpname); error(SYSTEM, errmsg); @@ -96,9 +103,16 @@ char *infn, *outfn; sprintf(errmsg, "cannot open \"%s\" for writing", outfn); error(SYSTEM, errmsg); } + /* set up signal handling */ + if (signal(SIGINT, quit) == SIG_IGN) signal(SIGINT, SIG_IGN); + if (signal(SIGHUP, quit) == SIG_IGN) signal(SIGHUP, SIG_IGN); + if (signal(SIGTERM, quit) == SIG_IGN) signal(SIGTERM, SIG_IGN); +#ifdef SIGXCPU + if (signal(SIGXCPU, quit) == SIG_IGN) signal(SIGXCPU, SIG_IGN); + if (signal(SIGXFSZ, quit) == SIG_IGN) signal(SIGXFSZ, SIG_IGN); +#endif /* copy and verify header */ - if (checkheader(infp, HOLOFMT, outfp) < 0 || - getw(infp) != HOLOMAGIC) + if (checkheader(infp, HOLOFMT, outfp) < 0 || getw(infp) != HOLOMAGIC) error(USER, "input not in holodeck format"); fputformat(HOLOFMT, outfp); fputc('\n', outfp); @@ -111,152 +125,63 @@ char *infn, *outfn; fclose(infp); if (fclose(outfp) == EOF) error(SYSTEM, "file flushing error in rhinitcopy"); - /* we flush everything manually */ - hdcachesize = 0; + /* check cache size */ + if (BKBSIZE*1024*1.5 > hdcachesize) + hdcachesize = BKBSIZE*1024*1.5; /* return input position */ return(ifpos); } -gcshifti(gc, ia, di, hp) /* shift cell row or column */ -register GCOORD *gc; -int ia, di; -register HOLO *hp; +static BEAMI *beamdir; + +static int +bpcmp(b1p, b2p) /* compare beam positions on disk */ +int *b1p, *b2p; { - int nw; + register long pdif = beamdir[*b1p].fo - beamdir[*b2p].fo; - if (di > 0) { - if (++gc->i[ia] >= hp->grid[((gc->w>>1)+1+ia)%3]) { - nw = ((gc->w&~1) + (ia<<1) + 3) % 6; - gc->i[ia] = gc->i[1-ia]; - gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0; - gc->w = nw; - } - } else if (di < 0) { - if (--gc->i[ia] < 0) { - nw = ((gc->w&~1) + (ia<<1) + 2) % 6; - gc->i[ia] = gc->i[1-ia]; - gc->i[1-ia] = gc->w&1 ? hp->grid[((nw>>1)+2-ia)%3]-1 : 0; - gc->w = nw; - } - } + if (pdif > 0L) return(1); + if (pdif < 0L) return(-1); + return(0); } +static HOLO *hout; -mkneighgrid(ng, hp, gc) /* compute neighborhood for grid cell */ -GCOORD ng[3*3]; +static int +xferclump(hp, bq, nb) /* transfer the given clump to hout and free */ HOLO *hp; -GCOORD *gc; +int *bq, nb; { - GCOORD gci0; - int i, j; + register int i; + register BEAM *bp; - for (i = 3; i--; ) { - copystruct(&gci0, gc); - gcshifti(&gci0, 0, i-1, hp); - for (j = 3; j--; ) { - copystruct(ng+(3*i+j), &gci0); - gcshifti(ng+(3*i+j), 1, j-1, hp); - } + beamdir = hp->bi; /* sort based on file position */ + qsort((char *)bq, nb, sizeof(*bq), bpcmp); + /* transfer and free each beam */ + for (i = 0; i < nb; i++) { + bp = hdgetbeam(hp, bq[i]); + bcopy((char *)hdbray(bp), (char *)hdnewrays(hout,bq[i],bp->nrm), + bp->nrm*sizeof(RAYVAL)); + hdfreebeam(hp, bq[i]); } + hdflush(hout); /* write & free clump */ + return(0); } - -int bneighlist[9*9-1]; -int bneighrem; - -#define nextneigh() (bneighrem<=0 ? 0 : bneighlist[--bneighrem]) - -int -firstneigh(hp, b) /* initialize neighbor list and return first */ -HOLO *hp; -int b; -{ - GCOORD wg0[9], wg1[9], bgc[2]; - int i, j; - - hdbcoord(bgc, hp, b); - mkneighgrid(wg0, hp, bgc); - mkneighgrid(wg1, hp, bgc+1); - bneighrem = 0; - for (i = 9; i--; ) - for (j = 9; j--; ) { - if (i == 4 & j == 4) - continue; - copystruct(bgc, wg0+i); - copystruct(bgc+1, wg1+j); - bneighlist[bneighrem++] = hdbindex(hp, bgc); - } - return(nextneigh()); -} - - copysect(ifd, ofd) /* copy holodeck section from ifd to ofd */ int ifd, ofd; { -#define beamdone(b) (!hinp->bi[b].nrd || bnrays(hout,b)) - static short primes[] = {9431,6803,4177,2659,1609,887,587,251,47,1}; - register HOLO *hinp, *hout; - register BEAM *bp; - int *bqueue; - int bqlen; - int4 bqtotal; - int bc, bci, bqc, bnc, myprime; - register int i; + HOLO *hinp; /* load input section directory */ hinp = hdinit(ifd, NULL); /* create output section directory */ hout = hdinit(ofd, (HDGRID *)hinp); - /* allocate beam queue */ - if ((bqueue = (int *)malloc(nbeams(hinp)*sizeof(int))) == NULL) - error(SYSTEM, "out of memory in copysect"); - /* pick a good prime step size */ - for (i = 0; primes[i]<<5 >= nbeams(hinp); i++) - ; - while ((myprime = primes[i++]) > 1) - if (nbeams(hinp) % myprime) - break; - /* add each input beam and neighbors */ - for (bc = bci = nbeams(hinp); bc > 0; bc--, - bci += bci>myprime ? -myprime : nbeams(hinp)-myprime) { - if (beamdone(bci)) - continue; - bqueue[0] = bci; /* initialize queue */ - bqlen = 1; - bqtotal = bnrays(hinp, bci); - /* run through growing queue */ - for (bqc = 0; bqc < bqlen; bqc++) { - /* transfer the beam */ - bp = hdgetbeam(hinp, bqueue[bqc]); - bcopy((char *)hdbray(bp), - (char *)hdnewrays(hout,bqueue[bqc],bp->nrm), - bp->nrm*sizeof(RAYVAL)); - hdfreebeam(hinp, bqueue[bqc]); - /* check queue size */ - if (bqtotal >= BKBSIZE*1024/sizeof(RAYVAL)) - continue; - /* add neighbors to queue */ - for (bnc = firstneigh(hinp,bqueue[bqc]); bnc > 0; - bnc = nextneigh()) { - if (beamdone(bnc)) /* see if valid */ - continue; - for (i = bqlen; i--; ) - if (bqueue[i] == bnc) break; - if (i >= 0) - continue; - bqueue[bqlen++] = bnc; /* add it */ - bqtotal += bnrays(hinp, bnc); - if (bqtotal >= BKBSIZE*1024/sizeof(RAYVAL)) - break; /* queue full */ - } - } - hdfreebeam(hout, 0); /* flush output block */ - } - /* we're done -- clean up */ - free((char *)bqueue); + /* clump the beams */ + clumpbeams(hinp, 0, BKBSIZE*1024, xferclump); + /* clean up */ hddone(hinp); hddone(hout); -#undef beamdone } @@ -282,6 +207,7 @@ register char *s; quit(code) /* exit the program gracefully */ int code; { - hdsync(NULL, 1); /* write out any buffered data */ + if (tempfile[0]) + unlink(tempfile); exit(code); }