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.9 by greg, Thu Jun 14 05:13:25 2012 UTC vs.
Revision 2.10 by greg, Sat Jun 16 17:09:49 2012 UTC

# Line 11 | Line 11 | static const char RCSid[] = "$Id$";
11   #include "rtprocess.h"
12   #include "selcall.h"
13  
14 + #define MAXIQ           (int)(PIPE_BUF/(sizeof(FVECT)*2))
15 +
16   /* Modifier contribution queue (results waiting to be output) */
17   typedef struct s_binq {
18          RNUMBER         ndx;            /* index for this entry */
# Line 26 | Line 28 | static struct {
28          RNUMBER r1;                     /* assigned ray starting index */
29          SUBPROC pr;                     /* PID, i/o descriptors */
30          FILE    *infp;                  /* file pointer to read from process */
31 <        int     nr;                     /* number rays to sum (0 if free) */
31 >        int     nr;                     /* number of rays to sum (0 if free) */
32   } kida[MAXPROCESS];             /* our child processes */
33  
34  
# Line 94 | Line 96 | free_binq(BINQ *bp)
96  
97  
98   /* Add modifier values to accumulation record in queue and clear */
99 < void
99 > static void
100   queue_modifiers()
101   {
102          MODCONT *mpin, *mpout;
# Line 146 | Line 148 | queue_output(BINQ *bp)
148                  }
149                  return;
150          }
151 <        b_last = NULL;                  /* else insert in output queue */
151 >        b_last = NULL;                  /* insert in output queue */
152          for (b_cur = out_bq; b_cur != NULL && b_cur->ndx < bp->ndx;
153                                  b_cur = b_cur->next)
154                  b_last = b_cur;
# Line 184 | Line 186 | queue_ready()
186          int     nready = 0;
187          BINQ    *bp;
188  
187        if (accumulate <= 0)            /* just accumulating? */
188                return(0);
189
189          for (bp = out_bq; bp != NULL && bp->nadded >= accumulate &&
190                                  bp->ndx == lastdone+nready*accumulate+1;
191                                  bp = bp->next)
# Line 203 | Line 202 | output_catchup(int nmax)
202          int     nout = 0;
203          BINQ    *bp;
204          int     i;
205 <
207 <        if (accumulate <= 0)            /* just accumulating? */
208 <                return(0);
209 <                                        /* else output ready results */
205 >                                        /* output ready results */
206          while (out_bq != NULL && out_bq->nadded >= accumulate
207                                  && out_bq->ndx == lastdone+1) {
208                  if ((nmax > 0) & (nout >= nmax))
# Line 401 | Line 397 | tryagain:                              /* catch up with output? */
397   void
398   parental_loop()
399   {
404 #define MAXIQ           (int)(PIPE_BUF/(sizeof(FVECT)*2))
400          static int      ignore_warning_given = 0;
401          int             qlimit = (accumulate == 1) ? 1 : MAXIQ-1;
402          int             ninq = 0;
# Line 427 | Line 422 | parental_loop()
422                          if ((yres <= 0) | (xres <= 0))
423                                  waitflush = 1;          /* flush next */
424                          put_zero_record(++lastray);
425 <                } else if (++ninq >= qlimit || accumulate > 1 &&
425 >                } else if (++ninq >= qlimit ||
426                              lastray/accumulate != (lastray+ninq)/accumulate) {
427                          i = next_child_nq(0);           /* manages output */
428                          n = ninq;
# Line 450 | Line 445 | parental_loop()
445          }
446          while (next_child_nq(1) >= 0)           /* empty results queue */
447                  ;
448 <                                                /* output accumulated record */
449 <        if (accumulate <= 0 || account < accumulate) {
450 <                end_children();                 /* frees up file descriptors */
456 <                if (account < accumulate) {
457 <                        error(WARNING, "partial accumulation in final record");
458 <                        accumulate -= account;
459 <                }
460 <                for (i = 0; i < nmods; i++)
461 <                        mod_output(out_bq->mca[i]);
462 <                end_record();
463 <                free_binq(out_bq);
448 >        if (account < accumulate) {
449 >                error(WARNING, "partial accumulation in final record");
450 >                free_binq(out_bq);              /* XXX just ignore it */
451                  out_bq = NULL;
452          }
453 +        free_binq(NULL);                        /* clean up */
454 +        lu_done(&ofiletab);
455          if (raysleft)
456                  error(USER, "unexpected EOF on input");
457 <        free_binq(NULL);                        /* clean up */
457 > }
458 >
459 >
460 > /* Wait for the next available child by monitoring "to" pipes */
461 > static int
462 > next_child_ready()
463 > {
464 >        fd_set                  writeset, errset;
465 >        int                     i, n, nqr;
466 >
467 >        for (i = nchild; i--; )         /* see if there's one free first */
468 >                if (!kida[i].nr)
469 >                        return(i);
470 >                                        /* prepare select() call */
471 >        FD_ZERO(&writeset); FD_ZERO(&errset);
472 >        n = 0;
473 >        for (i = nchild; i--; ) {
474 >                FD_SET(kida[i].pr.w, &writeset);
475 >                FD_SET(kida[i].pr.r, &errset);
476 >                if (kida[i].pr.w >= n)
477 >                        n = kida[i].pr.w + 1;
478 >                if (kida[i].pr.r >= n)
479 >                        n = kida[i].pr.r + 1;
480 >        }
481 >        errno = 0;
482 >        n = select(n, NULL, &writeset, &errset, NULL);
483 >        if (n < 0)
484 >                error(SYSTEM, "select() error in next_child_ready()");
485 >        n = -1;                         /* identify waiting child */
486 >        for (i = nchild; i--; ) {
487 >                if (FD_ISSET(kida[i].pr.r, &errset))
488 >                        error(USER, "rendering process died");
489 >                if (FD_ISSET(kida[i].pr.w, &writeset))
490 >                        kida[n = i].nr = 0;
491 >        }
492 >        return(n);                      /* first available child */
493 > }
494 >
495 >
496 > /* Modified parental loop for full accumulation mode (-c 0) */
497 > void
498 > feeder_loop()
499 > {
500 >        static int      ignore_warning_given = 0;
501 >        int             ninq = 0;
502 >        FVECT           orgdir[2*MAXIQ];
503 >        int             i, n;
504 >                                        /* load rays from stdin & process */
505 > #ifdef getc_unlocked
506 >        flockfile(stdin);               /* avoid lock/unlock overhead */
507 > #endif
508 >        while (getvec(orgdir[2*ninq]) == 0 && getvec(orgdir[2*ninq+1]) == 0) {
509 >                if (orgdir[2*ninq+1][0] == 0.0 &&       /* asking for flush? */
510 >                                (orgdir[2*ninq+1][1] == 0.0) &
511 >                                (orgdir[2*ninq+1][2] == 0.0)) {
512 >                        if (!ignore_warning_given++)
513 >                                error(WARNING,
514 >                                "dummy ray(s) ignored during accumulation\n");
515 >                        continue;
516 >                }
517 >                if (++ninq >= MAXIQ) {
518 >                        i = next_child_ready();         /* get eager child */
519 >                        n = sizeof(FVECT)*2 * ninq;     /* give assignment */
520 >                        if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
521 >                                error(SYSTEM, "pipe write error");
522 >                        kida[i].r1 = lastray+1;
523 >                        lastray += kida[i].nr = ninq;
524 >                        ninq = 0;
525 >                        if (lastray < lastdone)         /* RNUMBER wrapped? */
526 >                                lastdone = lastray = 0;
527 >                }
528 >                if (raysleft && !--raysleft)
529 >                        break;                          /* preemptive EOI */
530 >        }
531 >        if (ninq) {                             /* polish off input */
532 >                i = next_child_ready();
533 >                n = sizeof(FVECT)*2 * ninq;
534 >                if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
535 >                        error(SYSTEM, "pipe write error");
536 >                kida[i].r1 = lastray+1;
537 >                lastray += kida[i].nr = ninq;
538 >                ninq = 0;
539 >        }
540 >        for (i = nchild; i--; ) {               /* get results */
541 >                close(kida[i].pr.w);
542 >                queue_results(i);
543 >        }
544 >        if (recover)                            /* and from before? */
545 >                queue_modifiers();
546 >        end_children();                         /* free up file descriptors */
547 >        for (i = 0; i < nmods; i++)
548 >                mod_output(out_bq->mca[i]);     /* output accumulated record */
549 >        end_record();
550 >        free_binq(out_bq);                      /* clean up */
551 >        out_bq = NULL;
552 >        free_binq(NULL);
553          lu_done(&ofiletab);
554 < #undef MAXIQ
554 >        if (raysleft)
555 >                error(USER, "unexpected EOF on input");
556   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines