ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rc3.c
(Generate patch)

Comparing ray/src/rt/rc3.c (file contents):
Revision 2.16 by greg, Fri Jun 22 21:58:45 2012 UTC vs.
Revision 2.22 by greg, Thu Aug 18 00:52:48 2016 UTC

# Line 23 | Line 23 | typedef struct s_binq {
23   static BINQ     *out_bq = NULL;         /* output bin queue */
24   static BINQ     *free_bq = NULL;        /* free queue entries */
25  
26 + static SUBPROC  kidpr[MAXPROCESS];      /* our child processes */
27 +
28   static struct {
29          RNUMBER r1;                     /* assigned ray starting index */
28        SUBPROC pr;                     /* PID, i/o descriptors */
30          FILE    *infp;                  /* file pointer to read from process */
31          int     nr;                     /* number of rays to sum (0 if free) */
32 < } kida[MAXPROCESS];             /* our child processes */
32 > } kida[MAXPROCESS];             /* our child process i/o */
33  
34  
35   /* Get new bin queue entry */
# Line 247 | Line 248 | queue_results(int k)
248          bq->nadded = kida[k].nr;
249                                          /* read from child */
250          for (j = 0; j < nmods; j++)
251 <                if (fread(bq->mca[j]->cbin, sizeof(DCOLOR), bq->mca[j]->nbins,
251 >                if (getbinary(bq->mca[j]->cbin, sizeof(DCOLOR), bq->mca[j]->nbins,
252                                          kida[k].infp) != bq->mca[j]->nbins)
253                          error(SYSTEM, "read error from render process");
254                          
# Line 265 | Line 266 | set_stdout(const LUENT *le, void *p)
266   }
267  
268  
269 < /* Start child processes if we can */
269 > /* Start child processes if we can (call only once in parent!) */
270   int
271   in_rchild()
272   {
# Line 273 | Line 274 | in_rchild()
274  
275          while (nchild < nproc) {        /* fork until target reached */
276                  errno = 0;
277 <                rval = open_process(&kida[nchild].pr, NULL);
277 >                rval = open_process(&kidpr[nchild], NULL);
278                  if (rval < 0)
279                          error(SYSTEM, "open_process() call failed");
280                  if (rval == 0) {        /* if in child, set up & return true */
281 <                        lu_doall(&modconttab, set_stdout, NULL);
281 >                        lu_doall(&modconttab, &set_stdout, NULL);
282                          lu_done(&ofiletab);
283                          while (nchild--) {      /* don't share other pipes */
284 <                                close(kida[nchild].pr.w);
284 >                                close(kidpr[nchild].w);
285                                  fclose(kida[nchild].infp);
286                          }
287                          inpfmt = (sizeof(RREAL)==sizeof(double)) ? 'd' : 'f';
# Line 300 | Line 301 | in_rchild()
301                  if (rval != PIPE_BUF)
302                          error(CONSISTENCY, "bad value from open_process()");
303                                          /* connect to child's output */
304 <                kida[nchild].infp = fdopen(kida[nchild].pr.r, "rb");
304 >                kida[nchild].infp = fdopen(kidpr[nchild].r, "rb");
305                  if (kida[nchild].infp == NULL)
306                          error(SYSTEM, "out of memory in in_rchild()");
306 #ifdef getc_unlocked
307                flockfile(kida[nchild].infp);   /* avoid mutex overhead */
308 #endif
307                  kida[nchild++].nr = 0;  /* mark as available */
308          }
309 + #ifdef getc_unlocked
310 +        for (rval = nchild; rval--; )   /* avoid mutex overhead */
311 +                flockfile(kida[rval].infp);
312 + #endif
313          return(0);                      /* return "false" in parent */
314   }
315  
# Line 316 | Line 318 | in_rchild()
318   void
319   end_children(int immed)
320   {
321 <        int     status;
322 <        
323 <        while (nchild > 0) {
324 <                nchild--;
325 < #ifdef SIGKILL
324 <                if (immed)              /* error mode -- quick exit */
325 <                        kill(kida[nchild].pr.pid, SIGKILL);
321 >        int     i;
322 >
323 > #ifdef SIGKILL                          /* error mode -- quick exit */
324 >        for (i = nchild*immed; i-- > 0; )
325 >                kill(kidpr[nchild].pid, SIGKILL);
326   #endif
327 <                if ((status = close_process(&kida[nchild].pr)) > 0 && !immed) {
328 <                        sprintf(errmsg,
329 <                                "rendering process returned bad status (%d)",
330 <                                        status);
327 >        if ((i = close_processes(kidpr, nchild)) > 0 && !immed) {
328 >                sprintf(errmsg, "rendering process returned bad status (%d)",
329 >                                        i);
330                          error(WARNING, errmsg);
332                }
333                fclose(kida[nchild].infp);
331          }
332 +        while (nchild-- > 0)
333 +                fclose(kida[nchild].infp);
334   }
335  
336  
# Line 365 | Line 364 | tryagain:                              /* catch up with output? */
364          n = nr = 0;
365          for (i = nchild; i--; ) {
366                  if (kida[i].nr) {
367 <                        FD_SET(kida[i].pr.r, &readset);
367 >                        FD_SET(kidpr[i].r, &readset);
368                          ++nr;
369                  }
370 <                FD_SET(kida[i].pr.r, &errset);
371 <                if (kida[i].pr.r >= n)
372 <                        n = kida[i].pr.r + 1;
370 >                FD_SET(kidpr[i].r, &errset);
371 >                if (kidpr[i].r >= n)
372 >                        n = kidpr[i].r + 1;
373          }
374          if (!nr)                        /* nothing to wait for? */
375                  return(-1);
# Line 387 | Line 386 | tryagain:                              /* catch up with output? */
386                  FD_ZERO(&errset);
387          n = -1;                         /* read results from child(ren) */
388          for (i = nchild; i--; ) {
389 <                if (FD_ISSET(kida[i].pr.r, &errset))
389 >                if (FD_ISSET(kidpr[i].r, &errset))
390                          error(USER, "rendering process died");
391 <                if (FD_ISSET(kida[i].pr.r, &readset))
391 >                if (FD_ISSET(kidpr[i].r, &readset))
392                          queue_results(n = i);
393          }
394          return(n);                      /* first available child */
# Line 400 | Line 399 | tryagain:                              /* catch up with output? */
399   void
400   parental_loop()
401   {
402 <        static int      ignore_warning_given = 0;
404 <        int             qlimit = (accumulate == 1) ? 1 : MAXIQ-1;
402 >        const int       qlimit = (accumulate == 1) ? 1 : MAXIQ-1;
403          int             ninq = 0;
404          FVECT           orgdir[2*MAXIQ];
405          int             i, n;
# Line 410 | Line 408 | parental_loop()
408          flockfile(stdin);               /* avoid lock/unlock overhead */
409   #endif
410          while (getvec(orgdir[2*ninq]) == 0 && getvec(orgdir[2*ninq+1]) == 0) {
411 <                if (orgdir[2*ninq+1][0] == 0.0 &&       /* asking for flush? */
412 <                                (orgdir[2*ninq+1][1] == 0.0) &
413 <                                (orgdir[2*ninq+1][2] == 0.0)) {
414 <                        if (accumulate != 1) {
415 <                                if (!ignore_warning_given++)
416 <                                        error(WARNING,
419 <                                "dummy ray(s) ignored during accumulation\n");
420 <                                continue;
421 <                        }
422 <                        while (next_child_nq(1) >= 0)
423 <                                ;                       /* clear the queue */
424 <                        lastdone = lastray = 0;
425 <                        if ((yres <= 0) | (xres <= 0))
426 <                                waitflush = 1;          /* flush next */
427 <                        put_zero_record(++lastray);
428 <                } else if (++ninq >= qlimit ||
411 >                const int       zero_ray = orgdir[2*ninq+1][0] == 0.0 &&
412 >                                                (orgdir[2*ninq+1][1] == 0.0) &
413 >                                                (orgdir[2*ninq+1][2] == 0.0);
414 >                ninq += !zero_ray;
415 >                                /* Zero ray cannot go in input queue */
416 >                if (zero_ray ? ninq : ninq >= qlimit ||
417                              lastray/accumulate != (lastray+ninq)/accumulate) {
418                          i = next_child_nq(0);           /* manages output */
419                          n = ninq;
420 <                        if (accumulate != 1)            /* request flush? */
420 >                        if (accumulate > 1)             /* need terminator? */
421                                  memset(orgdir[2*n++], 0, sizeof(FVECT)*2);
422                          n *= sizeof(FVECT)*2;           /* send assignment */
423 <                        if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
423 >                        if (writebuf(kidpr[i].w, (char *)orgdir, n) != n)
424                                  error(SYSTEM, "pipe write error");
425                          kida[i].r1 = lastray+1;
426                          lastray += kida[i].nr = ninq;   /* mark as busy */
439                        ninq = 0;
427                          if (lastray < lastdone) {       /* RNUMBER wrapped? */
428                                  while (next_child_nq(1) >= 0)
429                                          ;
430 <                                lastdone = lastray = 0;
430 >                                lastray -= ninq;
431 >                                lastdone = lastray %= accumulate;
432                          }
433 +                        ninq = 0;
434                  }
435 +                if (zero_ray) {                         /* put bogus record? */
436 +                        if ((yres <= 0) | (xres <= 1) &&
437 +                                        (lastray+1) % accumulate == 0) {
438 +                                while (next_child_nq(1) >= 0)
439 +                                        ;               /* clear the queue */
440 +                                lastdone = lastray = accumulate-1;
441 +                                waitflush = 1;          /* flush next */
442 +                        }
443 +                        put_zero_record(++lastray);
444 +                }
445                  if (raysleft && !--raysleft)
446                          break;                          /* preemptive EOI */
447          }
# Line 474 | Line 473 | next_child_ready()
473          FD_ZERO(&writeset); FD_ZERO(&errset);
474          n = 0;
475          for (i = nchild; i--; ) {
476 <                FD_SET(kida[i].pr.w, &writeset);
477 <                FD_SET(kida[i].pr.r, &errset);
478 <                if (kida[i].pr.w >= n)
479 <                        n = kida[i].pr.w + 1;
480 <                if (kida[i].pr.r >= n)
481 <                        n = kida[i].pr.r + 1;
476 >                FD_SET(kidpr[i].w, &writeset);
477 >                FD_SET(kidpr[i].r, &errset);
478 >                if (kidpr[i].w >= n)
479 >                        n = kidpr[i].w + 1;
480 >                if (kidpr[i].r >= n)
481 >                        n = kidpr[i].r + 1;
482          }
483          errno = 0;
484          n = select(n, NULL, &writeset, &errset, NULL);
# Line 487 | Line 486 | next_child_ready()
486                  error(SYSTEM, "select() error in next_child_ready()");
487          n = -1;                         /* identify waiting child */
488          for (i = nchild; i--; ) {
489 <                if (FD_ISSET(kida[i].pr.r, &errset))
489 >                if (FD_ISSET(kidpr[i].r, &errset))
490                          error(USER, "rendering process died");
491 <                if (FD_ISSET(kida[i].pr.w, &writeset))
491 >                if (FD_ISSET(kidpr[i].w, &writeset))
492                          kida[n = i].nr = 0;
493          }
494          return(n);                      /* first available child */
# Line 520 | Line 519 | feeder_loop()
519                  if (++ninq >= MAXIQ) {
520                          i = next_child_ready();         /* get eager child */
521                          n = sizeof(FVECT)*2 * ninq;     /* give assignment */
522 <                        if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
522 >                        if (writebuf(kidpr[i].w, (char *)orgdir, n) != n)
523                                  error(SYSTEM, "pipe write error");
524                          kida[i].r1 = lastray+1;
525                          lastray += kida[i].nr = ninq;
527                        ninq = 0;
526                          if (lastray < lastdone)         /* RNUMBER wrapped? */
527                                  lastdone = lastray = 0;
528 +                        ninq = 0;
529                  }
530                  if (raysleft && !--raysleft)
531                          break;                          /* preemptive EOI */
# Line 534 | Line 533 | feeder_loop()
533          if (ninq) {                             /* polish off input */
534                  i = next_child_ready();
535                  n = sizeof(FVECT)*2 * ninq;
536 <                if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
536 >                if (writebuf(kidpr[i].w, (char *)orgdir, n) != n)
537                          error(SYSTEM, "pipe write error");
538                  kida[i].r1 = lastray+1;
539                  lastray += kida[i].nr = ninq;
# Line 542 | Line 541 | feeder_loop()
541          }
542          memset(orgdir, 0, sizeof(FVECT)*2);     /* get results */
543          for (i = nchild; i--; ) {
544 <                writebuf(kida[i].pr.w, (char *)orgdir, sizeof(FVECT)*2);
544 >                writebuf(kidpr[i].w, (char *)orgdir, sizeof(FVECT)*2);
545                  queue_results(i);
546          }
547          if (recover)                            /* and from before? */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines