--- ray/src/hd/rholo.c 1997/12/12 18:23:08 3.22 +++ ray/src/hd/rholo.c 1998/01/04 18:36:43 3.34 @@ -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++) @@ -88,42 +90,41 @@ char *argv[]; default: goto userr; } - /* do we have a job? */ - if (outdev == NULL && ncprocs <= 0) - goto userr; /* get root file name */ + if (i >= argc) + goto userr; rootname(froot, hdkfile=argv[i++]); - /* load... */ - if (i < argc) { /* variables */ - loadvars(argv[i++]); - /* cmdline settings */ - for ( ; i < argc; i++) - if (setvariable(argv[i], matchvar) < 0) { - sprintf(errmsg, "unknown variable: %s", - argv[i]); - error(USER, errmsg); - } - /* check settings */ - checkvalues(); - /* load RIF if any */ + /* load variables? */ + if (i < argc) + if (argv[i][0] != '-' && argv[i][0] != '+') + loadvars(argv[i]); /* load variables from file */ + + if (i >= argc || argv[i][0] == '+') + loadholo(); /* load existing holodeck */ + + while (++i < argc) /* get command line settings */ + if (setvariable(argv[i], matchvar) < 0) { + sprintf(errmsg, "unknown variable: %s", argv[i]); + error(USER, errmsg); + } + /* check settings */ + checkvalues(); + /* load RIF if rtrace */ + if (ncprocs) getradfile(); + + 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); - } else { /* else load holodeck */ - loadholo(); - /* check settings */ - checkvalues(); - /* load RIF if any */ - getradfile(); - /* set defaults */ + creatholo(hdg); + } else /* else just set defaults */ setdefaults(NULL); - } /* initialize */ initrholo(); /* main loop */ @@ -133,7 +134,7 @@ char *argv[]; quit(0); userr: fprintf(stderr, -"Usage: %s {-n nprocs|-o disp} [-w][-f] output.hdk [control.hif [VAR=val ..]]\n", +"Usage: %s [-n nprocs][-o disp][-w][-f] output.hdk [control.hif|+|- [VAR=val ..]]\n", progname); quit(1); } @@ -147,7 +148,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]); @@ -202,11 +203,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.; /* set up memory cache */ if (outdev == NULL) hdcachesize = 0; /* manual flushing */ @@ -218,6 +214,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(); @@ -231,9 +234,11 @@ 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 (!vbool(OBSTRUCTIONS)) { + if (!vdef(OBSTRUCTIONS) || !vbool(OBSTRUCTIONS)) { freepacks[i].offset = (float *)bmalloc( RPACKSIZ*sizeof(float)*(i+1) ); if (freepacks[i].offset == NULL) @@ -267,40 +272,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,28 +327,12 @@ rholo() /* holodeck main loop */ } -report(t) /* report progress so far */ -time_t t; -{ - static time_t seconds2go = 1000000; - - if (t == 0L) - t = time(NULL); - sprintf(errmsg, "%ld packets (%ld rays) done after %.2f hours\n", - npacksdone, nraysdone, (t-starttime)/3600.); - eputs(errmsg); - if (seconds2go == 1000000) - seconds2go = vdef(REPORT) ? (long)(vflt(REPORT)*60. + .5) : 0L; - if (seconds2go) - reporttime = t + seconds2go; -} - - setdefaults(gp) /* set default values */ register HDGRID *gp; { extern char *atos(); register int i; + int n; double len[3], maxlen, d; char buf[64]; @@ -344,28 +340,16 @@ 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"); sprintf(vval(OCTREE), "%s.oct", froot); vdef(OCTREE)++; } - if (!vdef(OBSTRUCTIONS)) { - vval(OBSTRUCTIONS) = "T"; - vdef(OBSTRUCTIONS)++; - } if (!vdef(VDIST)) { 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)); @@ -373,29 +357,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); } @@ -403,7 +386,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 */ @@ -417,11 +401,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); + } } @@ -454,7 +450,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, @@ -469,14 +466,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); + } } @@ -495,15 +497,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; } @@ -565,10 +567,9 @@ int ec; { int status = 0; - if (hdlist[0] != NULL) { /* flush holodeck */ + if (hdlist[0] != NULL) { /* close holodeck */ if (nprocs > 0) - status = done_rtrace(); - hdflush(NULL); + status = done_rtrace(); /* calls hdsync() */ if (ncprocs > 0 && vdef(REPORT)) { long fsiz, fuse; fsiz = hdfilen(hdlist[0]->fd);