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.17 by greg, Thu Nov 15 15:26:52 2012 UTC vs.
Revision 2.25 by greg, Wed Nov 15 18:02:53 2023 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 51 | Line 52 | new_binq()
52                  goto memerr;
53          for (i = nmods; i--; ) {
54                  MODCONT *mp = (MODCONT *)lu_find(&modconttab,modname[i])->data;
55 <                bp->mca[i] = (MODCONT *)malloc(sizeof(MODCONT) +
55 <                                                sizeof(DCOLOR)*(mp->nbins-1));
55 >                bp->mca[i] = (MODCONT *)malloc(mcsize(mp->nbins));
56                  if (bp->mca[i] == NULL)
57                          goto memerr;
58 <                memcpy(bp->mca[i], mp, sizeof(MODCONT)-sizeof(DCOLOR));
59 <                /* memset(bp->mca[i]->cbin, 0, sizeof(DCOLOR)*mp->nbins); */
58 >                memcpy(bp->mca[i], mp, sizeof(MODCONT)-sizeof(DCOLORV));
59 >                /* memset(bp->mca[i]->cbin, 0, DCOLORSIZ*mp->nbins); */
60          }
61          bp->ndx = 0;
62          bp->nadded = 0;
# Line 86 | Line 86 | free_binq(BINQ *bp)
86          }
87                                          /* clear sums for next use */
88   /*      for (i = nmods; i--; )
89 <                memset(bp->mca[i]->cbin, 0, sizeof(DCOLOR)*bp->mca[i]->nbins);
89 >                memset(bp->mca[i]->cbin, 0, DCOLORSIZ*bp->mca[i]->nbins);
90   */
91 +        if (bp->next != NULL)
92 +                error(CONSISTENCY, "free_binq() handed list");
93          bp->ndx = 0;
94          bp->next = free_bq;             /* push onto free list */
95          free_bq = bp;
# Line 99 | Line 101 | static void
101   queue_modifiers()
102   {
103          MODCONT *mpin, *mpout;
104 <        int     i, j;
104 >        DCOLORV *ssrc, *sdst;
105 >        int     i;
106  
107          if ((accumulate > 0) | (out_bq == NULL))
108                  error(CONSISTENCY, "bad call to queue_modifiers()");
# Line 107 | Line 110 | queue_modifiers()
110          for (i = nmods; i--; ) {
111                  mpin = (MODCONT *)lu_find(&modconttab,modname[i])->data;
112                  mpout = out_bq->mca[i];
113 <                for (j = mpout->nbins; j--; )
114 <                        addcolor(mpout->cbin[j], mpin->cbin[j]);
115 <                memset(mpin->cbin, 0, sizeof(DCOLOR)*mpin->nbins);
113 >                ssrc = mcbin(mpin, mpin->nbins);
114 >                sdst = mcbin(mpout, mpout->nbins);
115 >                while (sdst > mpout->cbin)
116 >                        *--sdst += *--ssrc;
117 >                memset(mpin->cbin, 0, DCOLORSIZ*mpin->nbins);
118          }
119          out_bq->nadded++;
120   }
# Line 119 | Line 124 | queue_modifiers()
124   static void
125   add_modbin(BINQ *dst, BINQ *src)
126   {
127 <        int     i, j;
128 <        
127 >        MODCONT *mpin, *mpout;
128 >        DCOLORV *ssrc, *sdst;
129 >        int     i;
130 >
131          for (i = nmods; i--; ) {
132 <                MODCONT *mpin = src->mca[i];
133 <                MODCONT *mpout = dst->mca[i];
134 <                for (j = mpout->nbins; j--; )
135 <                        addcolor(mpout->cbin[j], mpin->cbin[j]);
132 >                mpin = src->mca[i];
133 >                mpout = dst->mca[i];
134 >                ssrc = mcbin(mpin, mpin->nbins);
135 >                sdst = mcbin(mpout, mpout->nbins);
136 >                while (sdst > mpout->cbin)
137 >                        *--sdst += *--ssrc;
138          }
139          dst->nadded += src->nadded;
140   }
# Line 228 | Line 237 | put_zero_record(int ndx)
237          int     i;
238  
239          for (i = nmods; i--; )
240 <                memset(bp->mca[i]->cbin, 0, sizeof(DCOLOR)*bp->mca[i]->nbins);
240 >                memset(bp->mca[i]->cbin, 0, DCOLORSIZ*bp->mca[i]->nbins);
241          bp->ndx = ndx;
242          bp->nadded = 1;
243          queue_output(bp);
# Line 247 | Line 256 | queue_results(int k)
256          bq->nadded = kida[k].nr;
257                                          /* read from child */
258          for (j = 0; j < nmods; j++)
259 <                if (fread(bq->mca[j]->cbin, sizeof(DCOLOR), bq->mca[j]->nbins,
259 >                if (getbinary(bq->mca[j]->cbin, DCOLORSIZ, bq->mca[j]->nbins,
260                                          kida[k].infp) != bq->mca[j]->nbins)
261                          error(SYSTEM, "read error from render process");
262                          
# Line 265 | Line 274 | set_stdout(const LUENT *le, void *p)
274   }
275  
276  
277 < /* Start child processes if we can */
277 > /* Start child processes if we can (call only once in parent!) */
278   int
279   in_rchild()
280   {
# Line 273 | Line 282 | in_rchild()
282  
283          while (nchild < nproc) {        /* fork until target reached */
284                  errno = 0;
285 <                rval = open_process(&kida[nchild].pr, NULL);
285 >                rval = open_process(&kidpr[nchild], NULL);
286                  if (rval < 0)
287                          error(SYSTEM, "open_process() call failed");
288                  if (rval == 0) {        /* if in child, set up & return true */
289 <                        lu_doall(&modconttab, set_stdout, NULL);
289 >                        lu_doall(&modconttab, &set_stdout, NULL);
290                          lu_done(&ofiletab);
291                          while (nchild--) {      /* don't share other pipes */
292 <                                close(kida[nchild].pr.w);
292 >                                close(kidpr[nchild].w);
293                                  fclose(kida[nchild].infp);
294                          }
295                          inpfmt = (sizeof(RREAL)==sizeof(double)) ? 'd' : 'f';
# Line 300 | Line 309 | in_rchild()
309                  if (rval != PIPE_BUF)
310                          error(CONSISTENCY, "bad value from open_process()");
311                                          /* connect to child's output */
312 <                kida[nchild].infp = fdopen(kida[nchild].pr.r, "rb");
312 >                kida[nchild].infp = fdopen(kidpr[nchild].r, "rb");
313                  if (kida[nchild].infp == NULL)
314                          error(SYSTEM, "out of memory in in_rchild()");
306 #ifdef getc_unlocked
307                flockfile(kida[nchild].infp);   /* avoid mutex overhead */
308 #endif
315                  kida[nchild++].nr = 0;  /* mark as available */
316          }
317 + #ifdef getc_unlocked
318 +        for (rval = nchild; rval--; )   /* avoid mutex overhead */
319 +                flockfile(kida[rval].infp);
320 + #endif
321          return(0);                      /* return "false" in parent */
322   }
323  
# Line 316 | Line 326 | in_rchild()
326   void
327   end_children(int immed)
328   {
329 <        int     status;
330 <        
331 <        while (nchild > 0) {
332 <                nchild--;
333 < #ifdef SIGKILL
324 <                if (immed)              /* error mode -- quick exit */
325 <                        kill(kida[nchild].pr.pid, SIGKILL);
329 >        int     i;
330 >
331 > #ifdef SIGKILL                          /* error mode -- quick exit */
332 >        for (i = nchild*immed; i-- > 0; )
333 >                kill(kidpr[nchild].pid, SIGKILL);
334   #endif
335 <                if ((status = close_process(&kida[nchild].pr)) > 0 && !immed) {
336 <                        sprintf(errmsg,
337 <                                "rendering process returned bad status (%d)",
330 <                                        status);
335 >        if ((i = close_processes(kidpr, nchild)) > 0 && !immed) {
336 >                sprintf(errmsg, "rendering process returned bad status (%d)",
337 >                                        i);
338                          error(WARNING, errmsg);
332                }
333                fclose(kida[nchild].infp);
339          }
340 +        while (nchild-- > 0)
341 +                fclose(kida[nchild].infp);
342   }
343  
344  
# Line 365 | Line 372 | tryagain:                              /* catch up with output? */
372          n = nr = 0;
373          for (i = nchild; i--; ) {
374                  if (kida[i].nr) {
375 <                        FD_SET(kida[i].pr.r, &readset);
375 >                        FD_SET(kidpr[i].r, &readset);
376                          ++nr;
377                  }
378 <                FD_SET(kida[i].pr.r, &errset);
379 <                if (kida[i].pr.r >= n)
380 <                        n = kida[i].pr.r + 1;
378 >                FD_SET(kidpr[i].r, &errset);
379 >                if (kidpr[i].r >= n)
380 >                        n = kidpr[i].r + 1;
381          }
382          if (!nr)                        /* nothing to wait for? */
383                  return(-1);
# Line 387 | Line 394 | tryagain:                              /* catch up with output? */
394                  FD_ZERO(&errset);
395          n = -1;                         /* read results from child(ren) */
396          for (i = nchild; i--; ) {
397 <                if (FD_ISSET(kida[i].pr.r, &errset))
397 >                if (FD_ISSET(kidpr[i].r, &errset))
398                          error(USER, "rendering process died");
399 <                if (FD_ISSET(kida[i].pr.r, &readset))
399 >                if (FD_ISSET(kidpr[i].r, &readset))
400                          queue_results(n = i);
401          }
402          return(n);                      /* first available child */
# Line 409 | Line 416 | parental_loop()
416          flockfile(stdin);               /* avoid lock/unlock overhead */
417   #endif
418          while (getvec(orgdir[2*ninq]) == 0 && getvec(orgdir[2*ninq+1]) == 0) {
419 <                if (orgdir[2*ninq+1][0] == 0.0 &&       /* asking for flush? */
420 <                                (orgdir[2*ninq+1][1] == 0.0) &
421 <                                (orgdir[2*ninq+1][2] == 0.0)) {
422 <                        if (ninq) {                     /* preempt our queue */
423 <                                i = next_child_nq(0);
424 <                                n = ninq;
418 <                                memset(orgdir[2*n++], 0, sizeof(FVECT)*2);
419 <                                n *= sizeof(FVECT)*2;
420 <                                if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
421 <                                        error(SYSTEM, "pipe write error");
422 <                                kida[i].r1 = lastray+1;
423 <                                lastray += kida[i].nr = ninq;
424 <                                ninq = 0;
425 <                        }
426 <                        if ((yres <= 0) | (xres <= 0) &&
427 <                                        (lastray+1) % accumulate == 0) {
428 <                                while (next_child_nq(1) >= 0)
429 <                                        ;               /* clear the queue */
430 <                                lastdone = lastray %= accumulate;
431 <                                waitflush = 1;          /* flush next */
432 <                        }
433 <                        put_zero_record(++lastray);
434 <                } else if (++ninq >= qlimit ||
419 >                const int       zero_ray = orgdir[2*ninq+1][0] == 0.0 &&
420 >                                                (orgdir[2*ninq+1][1] == 0.0) &
421 >                                                (orgdir[2*ninq+1][2] == 0.0);
422 >                ninq += !zero_ray;
423 >                                /* Zero ray cannot go in input queue */
424 >                if (zero_ray ? ninq : ninq >= qlimit ||
425                              lastray/accumulate != (lastray+ninq)/accumulate) {
426                          i = next_child_nq(0);           /* manages output */
427                          n = ninq;
428 <                        if (accumulate != 1)            /* request flush? */
428 >                        if (accumulate > 1)             /* need terminator? */
429                                  memset(orgdir[2*n++], 0, sizeof(FVECT)*2);
430                          n *= sizeof(FVECT)*2;           /* send assignment */
431 <                        if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
431 >                        if (writebuf(kidpr[i].w, (char *)orgdir, n) != n)
432                                  error(SYSTEM, "pipe write error");
433                          kida[i].r1 = lastray+1;
434                          lastray += kida[i].nr = ninq;   /* mark as busy */
# Line 450 | Line 440 | parental_loop()
440                          }
441                          ninq = 0;
442                  }
443 <                if (raysleft && !--raysleft)
443 >                if (zero_ray) {                         /* put bogus record? */
444 >                        if ((yres <= 0) | (xres <= 1) &&
445 >                                        (lastray+1) % accumulate == 0) {
446 >                                while (next_child_nq(1) >= 0)
447 >                                        ;               /* clear the queue */
448 >                                lastdone = lastray = accumulate-1;
449 >                                waitflush = 1;          /* flush next */
450 >                        }
451 >                        put_zero_record(++lastray);
452 >                }
453 >                if (!morays())
454                          break;                          /* preemptive EOI */
455          }
456          while (next_child_nq(1) >= 0)           /* empty results queue */
# Line 481 | Line 481 | next_child_ready()
481          FD_ZERO(&writeset); FD_ZERO(&errset);
482          n = 0;
483          for (i = nchild; i--; ) {
484 <                FD_SET(kida[i].pr.w, &writeset);
485 <                FD_SET(kida[i].pr.r, &errset);
486 <                if (kida[i].pr.w >= n)
487 <                        n = kida[i].pr.w + 1;
488 <                if (kida[i].pr.r >= n)
489 <                        n = kida[i].pr.r + 1;
484 >                FD_SET(kidpr[i].w, &writeset);
485 >                FD_SET(kidpr[i].r, &errset);
486 >                if (kidpr[i].w >= n)
487 >                        n = kidpr[i].w + 1;
488 >                if (kidpr[i].r >= n)
489 >                        n = kidpr[i].r + 1;
490          }
491          errno = 0;
492          n = select(n, NULL, &writeset, &errset, NULL);
# Line 494 | Line 494 | next_child_ready()
494                  error(SYSTEM, "select() error in next_child_ready()");
495          n = -1;                         /* identify waiting child */
496          for (i = nchild; i--; ) {
497 <                if (FD_ISSET(kida[i].pr.r, &errset))
497 >                if (FD_ISSET(kidpr[i].r, &errset))
498                          error(USER, "rendering process died");
499 <                if (FD_ISSET(kida[i].pr.w, &writeset))
499 >                if (FD_ISSET(kidpr[i].w, &writeset))
500                          kida[n = i].nr = 0;
501          }
502          return(n);                      /* first available child */
# Line 527 | Line 527 | feeder_loop()
527                  if (++ninq >= MAXIQ) {
528                          i = next_child_ready();         /* get eager child */
529                          n = sizeof(FVECT)*2 * ninq;     /* give assignment */
530 <                        if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
530 >                        if (writebuf(kidpr[i].w, (char *)orgdir, n) != n)
531                                  error(SYSTEM, "pipe write error");
532                          kida[i].r1 = lastray+1;
533                          lastray += kida[i].nr = ninq;
534                        ninq = 0;
534                          if (lastray < lastdone)         /* RNUMBER wrapped? */
535                                  lastdone = lastray = 0;
536 +                        ninq = 0;
537                  }
538 <                if (raysleft && !--raysleft)
538 >                if (!morays())
539                          break;                          /* preemptive EOI */
540          }
541          if (ninq) {                             /* polish off input */
542                  i = next_child_ready();
543                  n = sizeof(FVECT)*2 * ninq;
544 <                if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
544 >                if (writebuf(kidpr[i].w, (char *)orgdir, n) != n)
545                          error(SYSTEM, "pipe write error");
546                  kida[i].r1 = lastray+1;
547                  lastray += kida[i].nr = ninq;
# Line 549 | Line 549 | feeder_loop()
549          }
550          memset(orgdir, 0, sizeof(FVECT)*2);     /* get results */
551          for (i = nchild; i--; ) {
552 <                writebuf(kida[i].pr.w, (char *)orgdir, sizeof(FVECT)*2);
552 >                writebuf(kidpr[i].w, (char *)orgdir, sizeof(FVECT)*2);
553                  queue_results(i);
554          }
555          if (recover)                            /* and from before? */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines