--- ray/src/hd/rholo.c 1997/12/15 20:43:01 3.28 +++ ray/src/hd/rholo.c 1998/01/16 11:45:43 3.37 @@ -1,4 +1,4 @@ -/* Copyright (c) 1997 Silicon Graphics, Inc. */ +/* Copyright (c) 1998 Silicon Graphics, Inc. */ #ifndef lint static char SCCSid[] = "$SunId$ SGI"; @@ -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) @@ -105,18 +109,19 @@ char *argv[]; } /* check settings */ checkvalues(); - /* load RIF if any */ + /* load rad input file */ 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); + creatholo(hdg); } else /* else just set defaults */ setdefaults(NULL); /* initialize */ @@ -170,7 +175,7 @@ int fd, mod; if (fstat(fd, &stbuf) < 0) error(SYSTEM, "cannot stat open holodeck file"); mod &= stbuf.st_mode; /* always more restrictive */ - if (mod == stbuf.st_mode) + if (mod == (stbuf.st_mode & 0777)) return(-1); /* already set */ /* else change it */ if (fchmod(fd, mod) < 0) { @@ -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,29 +271,28 @@ 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? */ - if (nprocs <= 0) { + /* check display */ + if (nprocs <= 0) idle = 1; - return(outdev != NULL); - } + 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(); 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(); @@ -292,10 +300,18 @@ rholo() /* holodeck main loop */ } if (reporttime > 0 && t >= reporttime) report(t); + /* 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,17 +331,14 @@ register HDGRID *gp; { extern char *atos(); register int i; - double len[3], maxlen, d; + int n; + double len[3], d; char buf[64]; if (!vdef(SECTION)) { 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"); @@ -343,29 +356,30 @@ 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); + for (i = 0; i < 3; i++) + len[i] = VLEN(gp->xv[i]); + if (!vdef(GRID)) { + d = 2/5e5*( len[0]*len[0]*(len[1]*len[1] + + len[2]*len[2] + 4*len[1]*len[2]) + + len[1]*len[1]*len[2]*(len[2] + 4*len[0]) + + 4*len[0]*len[1]*len[2]*len[2] ); + d = sqrt(sqrt(d)); + } 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); } @@ -373,7 +387,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 */ @@ -387,11 +402,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); + } } @@ -424,7 +451,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, @@ -439,14 +467,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); + } } @@ -465,15 +498,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; }