--- ray/src/hd/rholo.c 1997/12/14 09:46:52 3.27 +++ ray/src/hd/rholo.c 1997/12/31 20:45:31 3.33 @@ -14,6 +14,9 @@ static char SCCSid[] = "$SunId$ SGI"; #include #include +#ifndef MAXQTIME +#define MAXQTIME 5 /* target maximum seconds in queue */ +#endif /* the following must be consistent with rholo.h */ int NVARS = NRHVARS; /* total number of variables */ @@ -48,6 +51,7 @@ long nraysdone = 0L; /* number of rays done */ long npacksdone = 0L; /* number of packets done */ PACKET *freepacks; /* available packets */ +int avgqlen; /* average queue length when full */ char *sigerr[NSIG]; /* signal error messages */ @@ -58,10 +62,8 @@ main(argc, argv) int argc; char *argv[]; { - HDGRID hdg; int i; - /* mark start time */ - starttime = time(NULL); + initurand(16384); /* initialize urand */ progname = argv[0]; /* get arguments */ for (i = 1; i < argc && argv[i][0] == '-'; i++) @@ -89,6 +91,8 @@ char *argv[]; goto userr; } /* get root file name */ + if (i >= argc) + goto userr; rootname(froot, hdkfile=argv[i++]); /* load variables? */ if (i < argc) @@ -108,15 +112,16 @@ char *argv[]; /* load RIF if any */ getradfile(); - if (hdlist[i] == NULL) { /* create new holodeck */ + if (hdlist[0] == NULL) { /* create new holodeck */ + HDGRID hdg[HDMAX]; /* set defaults */ - setdefaults(&hdg); + setdefaults(hdg); /* holodeck exists? */ if (!force && access(hdkfile, R_OK|W_OK) == 0) error(USER, "holodeck file exists -- use -f to overwrite"); /* create holodeck */ - creatholo(&hdg); + creatholo(hdg); } else /* else just set defaults */ setdefaults(NULL); /* initialize */ @@ -142,7 +147,7 @@ int signo; if (gotsig++) /* two signals and we're gone! */ _exit(signo); - alarm(30); /* allow 30 seconds to clean up */ + alarm(60); /* allow 60 seconds to clean up */ signal(SIGALRM, SIG_DFL); /* make certain we do die */ eputs("signal - "); eputs(sigerr[signo]); @@ -197,11 +202,6 @@ initrholo() /* get our holodeck running */ maxdisk = 0; else maxdisk = 1024.*1024.*vflt(DISKSPACE); - /* record end time */ - if (!vdef(TIME) || vflt(TIME) <= FTINY) - endtime = 0; - else - endtime = starttime + vflt(TIME)*3600. + .5; /* set up memory cache */ if (outdev == NULL) hdcachesize = 0; /* manual flushing */ @@ -213,6 +213,13 @@ initrholo() /* get our holodeck running */ if (*s && freopen(s, "a", stderr) == NULL) quit(2); } + /* mark the starting time */ + starttime = time(NULL); + /* compute end time */ + if (!vdef(TIME) || vflt(TIME) <= FTINY) + endtime = 0; + else + endtime = starttime + vflt(TIME)*3600. + .5; /* start rtrace */ if (ncprocs > 0) { i = start_rtrace(); @@ -226,6 +233,8 @@ initrholo() /* get our holodeck running */ freepacks = (PACKET *)bmalloc(i*sizeof(PACKET)); if (freepacks == NULL) goto memerr; + if (!(avgqlen = i/nprocs)) /* record mean queue length */ + avgqlen = 1; freepacks[--i].nr = 0; freepacks[i].next = NULL; if (!vdef(OBSTRUCTIONS) || !vbool(OBSTRUCTIONS)) { @@ -262,40 +271,47 @@ memerr: rholo() /* holodeck main loop */ { - static int idle = 1; + static int idle = 0; PACKET *pl = NULL, *plend; + int pksiz; register PACKET *p; time_t t; - long l; - - if (outdev != NULL) /* check display */ - if (!disp_check(idle)) - return(0); - /* display only? */ + /* check display */ if (nprocs <= 0) - return(outdev != NULL); + idle = 1; + if (outdev != NULL) { + if (!disp_check(idle)) + return(0); /* quit request */ + if (nprocs <= 0) + return(1); + } else if (idle) + return(0); /* all done */ /* check file size */ if (maxdisk > 0 && hdfilen(hdlist[0]->fd) >= maxdisk) { error(WARNING, "file limit exceeded"); done_rtrace(); - idle = 1; return(1); /* comes back */ } - /* check time */ - if (endtime > 0 || reporttime > 0) - t = time(NULL); + t = time(NULL); /* check time */ if (endtime > 0 && t >= endtime) { error(WARNING, "time limit exceeded"); done_rtrace(); - idle = 1; return(1); /* comes back */ } if (reporttime > 0 && t >= reporttime) report(t); - /* get packets to process */ + /* figure out good packet size */ +#if MAXQTIME + pksiz = nraysdone*MAXQTIME/(avgqlen*(t - starttime + 1L)); + if (pksiz < 1) + pksiz = 1; + else if (pksiz > RPACKSIZ) +#endif + pksiz = RPACKSIZ; + idle = 0; /* get packets to process */ while (freepacks != NULL) { p = freepacks; freepacks = p->next; p->next = NULL; - if (!next_packet(p)) { + if (!next_packet(p, pksiz)) { p->next = freepacks; freepacks = p; idle = 1; break; @@ -315,6 +331,7 @@ register HDGRID *gp; { extern char *atos(); register int i; + int n; double len[3], maxlen, d; char buf[64]; @@ -322,10 +339,6 @@ register HDGRID *gp; sprintf(errmsg, "%s must be defined", vnam(SECTION)); error(USER, errmsg); } - if (vdef(SECTION) > 1) { - sprintf(errmsg, "ignoring all but first %s", vnam(SECTION)); - error(WARNING, errmsg); - } if (!vdef(OCTREE)) { if ((vval(OCTREE) = bmalloc(strlen(froot)+5)) == NULL) error(SYSTEM, "out of memory"); @@ -336,10 +349,6 @@ register HDGRID *gp; vval(VDIST) = "F"; vdef(VDIST)++; } - if (!vdef(OCCUPANCY)) { - vval(OCCUPANCY) = "U"; - vdef(OCCUPANCY)++; - } /* append rendering options */ if (vdef(RENDER)) rtargc += wordstring(rtargv+rtargc, vval(RENDER)); @@ -347,29 +356,28 @@ register HDGRID *gp; if (gp == NULL) /* already initialized? */ return; /* set grid parameters */ - gp->grid[0] = gp->grid[1] = gp->grid[2] = 0; - if (sscanf(vval(SECTION), + for (n = 0; n < vdef(SECTION); n++, gp++) { + gp->grid[0] = gp->grid[1] = gp->grid[2] = 0; + if (sscanf(nvalue(SECTION, n), "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %hd %hd %hd", - &gp->orig[0], &gp->orig[1], &gp->orig[2], - &gp->xv[0][0], &gp->xv[0][1], &gp->xv[0][2], - &gp->xv[1][0], &gp->xv[1][1], &gp->xv[1][2], - &gp->xv[2][0], &gp->xv[2][1], &gp->xv[2][2], - &gp->grid[0], &gp->grid[1], &gp->grid[2]) < 12) - badvalue(SECTION); - maxlen = 0.; - for (i = 0; i < 3; i++) - if ((len[i] = VLEN(gp->xv[i])) > maxlen) - maxlen = len[i]; - if (!vdef(GRID)) { - sprintf(buf, "%.4f", maxlen/8.); - vval(GRID) = savqstr(buf); - vdef(GRID)++; + &gp->orig[0], &gp->orig[1], &gp->orig[2], + &gp->xv[0][0], &gp->xv[0][1], &gp->xv[0][2], + &gp->xv[1][0], &gp->xv[1][1], &gp->xv[1][2], + &gp->xv[2][0], &gp->xv[2][1], &gp->xv[2][2], + &gp->grid[0], &gp->grid[1], &gp->grid[2]) < 12) + badvalue(SECTION); + maxlen = 0.; + for (i = 0; i < 3; i++) + if ((len[i] = VLEN(gp->xv[i])) > maxlen) + maxlen = len[i]; + if (!vdef(GRID)) + d = 0.125*maxlen; + else if ((d = vflt(GRID)) <= FTINY) + badvalue(GRID); + for (i = 0; i < 3; i++) + if (gp->grid[i] <= 0) + gp->grid[i] = len[i]/d + (1.-FTINY); } - if ((d = vflt(GRID)) <= FTINY) - badvalue(GRID); - for (i = 0; i < 3; i++) - if (gp->grid[i] <= 0) - gp->grid[i] = len[i]/d + (1.-FTINY); } @@ -377,7 +385,8 @@ creatholo(gp) /* create a holodeck output file */ HDGRID *gp; { extern char VersionID[]; - long endloc = 0; + int4 lastloc, nextloc; + int n; int fd; FILE *fp; /* open & truncate file */ @@ -391,11 +400,23 @@ HDGRID *gp; printvars(fp); fputformat(HOLOFMT, fp); fputc('\n', fp); - putw(HOLOMAGIC, fp); /* put magic number & terminus */ - fwrite(&endloc, sizeof(long), 1, fp); + putw(HOLOMAGIC, fp); /* put magic number */ fd = dup(fileno(fp)); fclose(fp); /* flush and close stdio stream */ - hdinit(fd, gp); /* allocate and initialize index */ + lastloc = lseek(fd, 0L, 2); + for (n = vdef(SECTION); n--; gp++) { /* initialize each section */ + nextloc = 0L; + write(fd, (char *)&nextloc, sizeof(nextloc)); + hdinit(fd, gp); /* writes beam index */ + if (!n) + break; + nextloc = hdfilen(fd); /* write section pointer */ + if (lseek(fd, (long)lastloc, 0) < 0) + error(SYSTEM, + "cannot seek on holodeck file in creatholo"); + write(fd, (char *)&nextloc, sizeof(nextloc)); + lseek(fd, (long)(lastloc=nextloc), 0); + } } @@ -428,7 +449,8 @@ loadholo() /* start loading a holodeck from fname */ extern long ftell(); FILE *fp; int fd; - long fpos; + int n; + int4 nextloc; /* open holodeck file */ if ((fp = fopen(hdkfile, ncprocs>0 ? "r+" : "r")) == NULL) { sprintf(errmsg, "cannot open \"%s\" for %s", hdkfile, @@ -443,14 +465,19 @@ loadholo() /* start loading a holodeck from fname */ hdkfile); error(USER, errmsg); } - fread(&fpos, sizeof(long), 1, fp); - if (fpos != 0) - error(WARNING, "ignoring multiple sections in holodeck file"); - fpos = ftell(fp); /* get stdio position */ + nextloc = ftell(fp); /* get stdio position */ fd = dup(fileno(fp)); fclose(fp); /* done with stdio */ - lseek(fd, fpos, 0); /* align system file pointer */ - hdinit(fd, NULL); /* allocate and load index */ + for (n = 0; nextloc > 0L; n++) { /* initialize each section */ + lseek(fd, (long)nextloc, 0); + read(fd, (char *)&nextloc, sizeof(nextloc)); + hdinit(fd, NULL); + } + if (n != vdef(SECTION)) { + sprintf(errmsg, "number of sections does not match %s setting", + vnam(SECTION)); + error(WARNING, errmsg); + } } @@ -469,15 +496,15 @@ PACKET *pl; if (outdev != NULL) /* display it */ disp_packet((PACKHEAD *)p); if (hdcachesize <= 0) /* manual flushing */ - n2flush += p->nr; + n2flush++; nraysdone += p->nr; npacksdone++; + p->nr = 0; } - p->nr = 0; /* push onto free list */ - p->next = freepacks; + p->next = freepacks; /* push onto free list */ freepacks = p; } - if (n2flush > 512*RPACKSIZ*nprocs) { + if (n2flush > 300/MAXQTIME*avgqlen*nprocs) { hdflush(NULL); /* flush holodeck buffers */ n2flush = 0; }