| 1 | < | /* Copyright (c) 1997 Silicon Graphics, Inc. */ | 
| 1 | > | /* Copyright (c) 1999 Silicon Graphics, Inc. */ | 
| 2 |  |  | 
| 3 |  | #ifndef lint | 
| 4 |  | static char SCCSid[] = "$SunId$ SGI"; | 
| 14 |  | #include <sys/types.h> | 
| 15 |  | #include <sys/stat.h> | 
| 16 |  |  | 
| 17 | + | #ifndef FRAGWARN | 
| 18 | + | #define FRAGWARN        20              /* fragmentation for warning (%) */ | 
| 19 | + | #endif | 
| 20 | + | #ifndef MAXQTIME | 
| 21 | + | #define MAXQTIME        5               /* target maximum seconds in queue */ | 
| 22 | + | #endif | 
| 23 | + | /* manual cache flushing frequency */ | 
| 24 | + | #ifndef RTFLUSH | 
| 25 | + | #if MAXQTIME | 
| 26 | + | #define RTFLUSH         (300/MAXQTIME*totqlen)  /* <= 5 minutes */ | 
| 27 | + | #else | 
| 28 | + | #define RTFLUSH         (50*totqlen)            /* just guess */ | 
| 29 | + | #endif | 
| 30 | + | #endif | 
| 31 |  | /* the following must be consistent with rholo.h */ | 
| 32 |  | int     NVARS = NRHVARS;                /* total number of variables */ | 
| 33 |  |  | 
| 37 |  | char    *hdkfile;               /* holodeck file name */ | 
| 38 |  | char    froot[256];             /* root file name */ | 
| 39 |  |  | 
| 26 | – | int     nowarn = 0;             /* turn warnings off? */ | 
| 27 | – |  | 
| 40 |  | int     ncprocs = 0;            /* desired number of compute processes */ | 
| 41 |  |  | 
| 42 |  | char    *outdev = NULL;         /* output device name */ | 
| 60 |  | long    npacksdone = 0L;        /* number of packets done */ | 
| 61 |  |  | 
| 62 |  | PACKET  *freepacks;             /* available packets */ | 
| 63 | + | int     totqlen;                /* maximum queue length (number of packets) */ | 
| 64 |  |  | 
| 65 |  | char  *sigerr[NSIG];            /* signal error messages */ | 
| 66 |  |  | 
| 67 | + | extern int      nowarn;         /* turn warnings off? */ | 
| 68 | + |  | 
| 69 |  | extern time_t   time(); | 
| 70 |  |  | 
| 71 |  |  | 
| 74 |  | char    *argv[]; | 
| 75 |  | { | 
| 76 |  | int     i; | 
| 77 | < | /* mark start time */ | 
| 63 | < | starttime = time(NULL); | 
| 77 | > |  | 
| 78 |  | initurand(16384);                       /* initialize urand */ | 
| 79 |  | progname = argv[0];                     /* get arguments */ | 
| 80 |  | for (i = 1; i < argc && argv[i][0] == '-'; i++) | 
| 102 |  | goto userr; | 
| 103 |  | } | 
| 104 |  | /* get root file name */ | 
| 105 | + | if (i >= argc) | 
| 106 | + | goto userr; | 
| 107 |  | rootname(froot, hdkfile=argv[i++]); | 
| 108 |  | /* load variables? */ | 
| 109 |  | if (i < argc) | 
| 120 |  | } | 
| 121 |  | /* check settings */ | 
| 122 |  | checkvalues(); | 
| 123 | < | /* load RIF if any */ | 
| 123 | > | /* load rad input file */ | 
| 124 |  | getradfile(); | 
| 125 |  |  | 
| 126 |  | if (hdlist[0] == NULL) {                /* create new holodeck */ | 
| 155 |  | { | 
| 156 |  | static int  gotsig = 0; | 
| 157 |  |  | 
| 158 | < | if (gotsig++)                   /* two signals and we're gone! */ | 
| 158 | > | if (gotsig > 1)                 /* we're going as fast as we can! */ | 
| 159 | > | return; | 
| 160 | > | if (gotsig++) {                 /* two signals and we split */ | 
| 161 | > | hdsync(NULL, 0);        /* don't leave w/o saying goodbye */ | 
| 162 |  | _exit(signo); | 
| 163 | < |  | 
| 164 | < | alarm(60);                      /* allow 60 seconds to clean up */ | 
| 146 | < | signal(SIGALRM, SIG_DFL);       /* make certain we do die */ | 
| 163 | > | } | 
| 164 | > | alarm(300);                     /* allow 5 minutes to clean up */ | 
| 165 |  | eputs("signal - "); | 
| 166 |  | eputs(sigerr[signo]); | 
| 167 |  | eputs("\n"); | 
| 188 |  | if (fstat(fd, &stbuf) < 0) | 
| 189 |  | error(SYSTEM, "cannot stat open holodeck file"); | 
| 190 |  | mod &= stbuf.st_mode;           /* always more restrictive */ | 
| 191 | < | if (mod == stbuf.st_mode) | 
| 191 | > | if (mod == (stbuf.st_mode & 0777)) | 
| 192 |  | return(-1);             /* already set */ | 
| 193 |  | /* else change it */ | 
| 194 |  | if (fchmod(fd, mod) < 0) { | 
| 215 |  | maxdisk = 0; | 
| 216 |  | else | 
| 217 |  | maxdisk = 1024.*1024.*vflt(DISKSPACE); | 
| 200 | – | /* record end time */ | 
| 201 | – | if (!vdef(TIME) || vflt(TIME) <= FTINY) | 
| 202 | – | endtime = 0; | 
| 203 | – | else | 
| 204 | – | endtime = starttime + vflt(TIME)*3600. + .5; | 
| 218 |  | /* set up memory cache */ | 
| 219 |  | if (outdev == NULL) | 
| 220 |  | hdcachesize = 0;        /* manual flushing */ | 
| 226 |  | if (*s && freopen(s, "a", stderr) == NULL) | 
| 227 |  | quit(2); | 
| 228 |  | } | 
| 229 | + | /* mark the starting time */ | 
| 230 | + | starttime = time(NULL); | 
| 231 | + | /* compute end time */ | 
| 232 | + | if (!vdef(TIME) || vflt(TIME) <= FTINY) | 
| 233 | + | endtime = 0; | 
| 234 | + | else | 
| 235 | + | endtime = starttime + vflt(TIME)*3600. + .5; | 
| 236 |  | /* start rtrace */ | 
| 237 |  | if (ncprocs > 0) { | 
| 238 | < | i = start_rtrace(); | 
| 238 | > | totqlen = i = start_rtrace(); | 
| 239 |  | if (i < 1) | 
| 240 |  | error(USER, "cannot start rtrace process(es)"); | 
| 241 |  | if (vdef(REPORT)) {             /* make first report */ | 
| 282 |  |  | 
| 283 |  | rholo()                         /* holodeck main loop */ | 
| 284 |  | { | 
| 285 | < | static int      idle = 1; | 
| 285 | > | static long     nextfragwarn = 100*(1L<<20); | 
| 286 | > | static int      idle = 0; | 
| 287 |  | PACKET  *pl = NULL, *plend; | 
| 288 | + | long    fsiz; | 
| 289 | + | int     pksiz; | 
| 290 |  | register PACKET *p; | 
| 291 |  | time_t  t; | 
| 292 | < | long    l; | 
| 293 | < |  | 
| 271 | < | if (outdev != NULL)             /* check display */ | 
| 272 | < | if (!disp_check(idle)) | 
| 273 | < | return(0); | 
| 274 | < | /* display only? */ | 
| 275 | < | if (nprocs <= 0) { | 
| 292 | > | /* check display */ | 
| 293 | > | if (nprocs <= 0) | 
| 294 |  | idle = 1; | 
| 295 | < | return(outdev != NULL); | 
| 296 | < | } | 
| 297 | < | /* check file size */ | 
| 298 | < | if (maxdisk > 0 && hdfilen(hdlist[0]->fd) >= maxdisk) { | 
| 295 | > | if (outdev != NULL) { | 
| 296 | > | if (!disp_check(idle)) | 
| 297 | > | return(0);      /* quit request */ | 
| 298 | > | if (nprocs <= 0) | 
| 299 | > | return(1); | 
| 300 | > | } else if (idle) | 
| 301 | > | return(0);              /* all done */ | 
| 302 | > | fsiz = hdfilen(hdlist[0]->fd);  /* check file size */ | 
| 303 | > | if (maxdisk > 0 && fsiz >= maxdisk) { | 
| 304 |  | error(WARNING, "file limit exceeded"); | 
| 305 |  | done_rtrace(); | 
| 306 |  | return(1);      /* comes back */ | 
| 307 |  | } | 
| 308 | < | /* check time */ | 
| 309 | < | if (endtime > 0 || reporttime > 0) | 
| 310 | < | t = time(NULL); | 
| 308 | > | #if FRAGWARN | 
| 309 | > | if (fsiz >= nextfragwarn && | 
| 310 | > | (fsiz-hdfiluse(hdlist[0]->fd,0))/(fsiz/100) > FRAGWARN) { | 
| 311 | > | sprintf(errmsg, "holodeck file fragmentation is %.0f%%", | 
| 312 | > | 100.*(fsiz-hdfiluse(hdlist[0]->fd,1))/fsiz); | 
| 313 | > | error(WARNING, errmsg); | 
| 314 | > | nextfragwarn = fsiz + (fsiz>>2);        /* decent interval */ | 
| 315 | > | } | 
| 316 | > | #endif | 
| 317 | > | t = time(NULL);                 /* check time */ | 
| 318 |  | if (endtime > 0 && t >= endtime) { | 
| 319 |  | error(WARNING, "time limit exceeded"); | 
| 320 |  | done_rtrace(); | 
| 322 |  | } | 
| 323 |  | if (reporttime > 0 && t >= reporttime) | 
| 324 |  | report(t); | 
| 325 | + | /* figure out good packet size */ | 
| 326 | + | pksiz = RPACKSIZ; | 
| 327 | + | #if MAXQTIME | 
| 328 | + | if (!chunkycmp) { | 
| 329 | + | pksiz = nraysdone*MAXQTIME/(totqlen*(t - starttime + 1L)); | 
| 330 | + | if (pksiz < 1) pksiz = 1; | 
| 331 | + | else if (pksiz > RPACKSIZ) pksiz = RPACKSIZ; | 
| 332 | + | } | 
| 333 | + | #endif | 
| 334 |  | idle = 0;                       /* get packets to process */ | 
| 335 |  | while (freepacks != NULL) { | 
| 336 |  | p = freepacks; freepacks = p->next; p->next = NULL; | 
| 337 | < | if (!next_packet(p)) { | 
| 337 | > | if (!next_packet(p, pksiz)) { | 
| 338 |  | p->next = freepacks; freepacks = p; | 
| 339 |  | idle = 1; | 
| 340 |  | break; | 
| 355 |  | extern char     *atos(); | 
| 356 |  | register int    i; | 
| 357 |  | int     n; | 
| 358 | < | double  len[3], maxlen, d; | 
| 358 | > | double  len[3], d; | 
| 359 |  | char    buf[64]; | 
| 360 |  |  | 
| 361 |  | if (!vdef(SECTION)) { | 
| 389 |  | &gp->xv[2][0], &gp->xv[2][1], &gp->xv[2][2], | 
| 390 |  | &gp->grid[0], &gp->grid[1], &gp->grid[2]) < 12) | 
| 391 |  | badvalue(SECTION); | 
| 353 | – | maxlen = 0.; | 
| 392 |  | for (i = 0; i < 3; i++) | 
| 393 | < | if ((len[i] = VLEN(gp->xv[i])) > maxlen) | 
| 394 | < | maxlen = len[i]; | 
| 395 | < | if (!vdef(GRID)) | 
| 396 | < | d = 0.125*maxlen; | 
| 397 | < | else if ((d = vflt(GRID)) <= FTINY) | 
| 393 | > | len[i] = VLEN(gp->xv[i]); | 
| 394 | > | if (!vdef(GRID)) { | 
| 395 | > | d = 2/2e5*( len[0]*len[0]*(len[1]*len[1] + | 
| 396 | > | len[2]*len[2] + 4*len[1]*len[2]) | 
| 397 | > | + len[1]*len[1]*len[2]*(len[2] + 4*len[0]) | 
| 398 | > | + 4*len[0]*len[1]*len[2]*len[2] ); | 
| 399 | > | d = sqrt(sqrt(d)); | 
| 400 | > | } else if ((d = vflt(GRID)) <= FTINY) | 
| 401 |  | badvalue(GRID); | 
| 402 |  | for (i = 0; i < 3; i++) | 
| 403 |  | if (gp->grid[i] <= 0) | 
| 445 |  | } | 
| 446 |  |  | 
| 447 |  |  | 
| 448 | + | int | 
| 449 |  | headline(s)                     /* process information header line */ | 
| 450 |  | char    *s; | 
| 451 |  | { | 
| 459 |  | HOLOFMT, hdkfile, FMTSTR, fmt); | 
| 460 |  | error(USER, errmsg); | 
| 461 |  | } | 
| 462 | < | return; | 
| 462 | > | return(0); | 
| 463 |  | } | 
| 464 |  | for (cp = s; *cp; cp++)         /* take off any comments */ | 
| 465 |  | if (*cp == '#') { | 
| 467 |  | break; | 
| 468 |  | } | 
| 469 |  | setvariable(s, matchvar);       /* don't flag errors */ | 
| 470 | + | return(0); | 
| 471 |  | } | 
| 472 |  |  | 
| 473 |  |  | 
| 480 |  | int4    nextloc; | 
| 481 |  | /* open holodeck file */ | 
| 482 |  | if ((fp = fopen(hdkfile, ncprocs>0 ? "r+" : "r")) == NULL) { | 
| 483 | < | sprintf(errmsg, "cannot open \"%s\" for %s", hdkfile, | 
| 484 | < | ncprocs>0 ? "appending" : "reading"); | 
| 483 | > | sprintf(errmsg, "cannot %s \"%s\"", | 
| 484 | > | ncprocs>0 ? "append" : "read", hdkfile); | 
| 485 |  | error(SYSTEM, errmsg); | 
| 486 |  | } | 
| 487 |  | /* load variables from header */ | 
| 522 |  | p->nr*sizeof(RAYVAL)); | 
| 523 |  | if (outdev != NULL)     /* display it */ | 
| 524 |  | disp_packet((PACKHEAD *)p); | 
| 525 | < | if (hdcachesize <= 0)   /* manual flushing */ | 
| 526 | < | n2flush += p->nr; | 
| 525 | > | if (hdcachesize <= 0) | 
| 526 | > | n2flush++; | 
| 527 |  | nraysdone += p->nr; | 
| 528 |  | npacksdone++; | 
| 529 | + | p->nr = 0; | 
| 530 |  | } | 
| 531 | < | p->nr = 0;                      /* push onto free list */ | 
| 488 | < | p->next = freepacks; | 
| 531 | > | p->next = freepacks;            /* push onto free list */ | 
| 532 |  | freepacks = p; | 
| 533 |  | } | 
| 534 | < | if (n2flush > 512*RPACKSIZ*nprocs) { | 
| 535 | < | hdflush(NULL);                  /* flush holodeck buffers */ | 
| 534 | > | if (n2flush > RTFLUSH) { | 
| 535 | > | if (outdev != NULL) | 
| 536 | > | hdsync(NULL, 1); | 
| 537 | > | else | 
| 538 | > | hdflush(NULL); | 
| 539 |  | n2flush = 0; | 
| 540 |  | } | 
| 541 |  | } | 
| 580 |  | fflush(stderr); | 
| 581 |  | midline = 0; | 
| 582 |  | } | 
| 537 | – | } | 
| 538 | – |  | 
| 539 | – |  | 
| 540 | – | wputs(s)                        /* put warning string to stderr */ | 
| 541 | – | char    *s; | 
| 542 | – | { | 
| 543 | – | if (!nowarn) | 
| 544 | – | eputs(s); | 
| 583 |  | } | 
| 584 |  |  | 
| 585 |  |  |