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.15 by greg, Thu Jun 21 17:14:32 2012 UTC vs.
Revision 2.23 by greg, Sun May 27 18:35:57 2018 UTC

# Line 8 | Line 8 | static const char RCSid[] = "$Id$";
8  
9   #include <signal.h>
10   #include "rcontrib.h"
11 #include "rtprocess.h"
11   #include "selcall.h"
12  
13   #define MAXIQ           (int)(PIPE_BUF/(sizeof(FVECT)*2))
# Line 24 | 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 */
29        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 89 | Line 89 | free_binq(BINQ *bp)
89   /*      for (i = nmods; i--; )
90                  memset(bp->mca[i]->cbin, 0, sizeof(DCOLOR)*bp->mca[i]->nbins);
91   */
92 +        if (bp->next != NULL)
93 +                error(CONSISTENCY, "free_binq() handed list");
94          bp->ndx = 0;
95          bp->next = free_bq;             /* push onto free list */
96          free_bq = bp;
# Line 248 | Line 250 | queue_results(int k)
250          bq->nadded = kida[k].nr;
251                                          /* read from child */
252          for (j = 0; j < nmods; j++)
253 <                if (fread(bq->mca[j]->cbin, sizeof(DCOLOR), bq->mca[j]->nbins,
253 >                if (getbinary(bq->mca[j]->cbin, sizeof(DCOLOR), bq->mca[j]->nbins,
254                                          kida[k].infp) != bq->mca[j]->nbins)
255                          error(SYSTEM, "read error from render process");
256                          
# Line 266 | Line 268 | set_stdout(const LUENT *le, void *p)
268   }
269  
270  
271 < /* Start child processes if we can */
271 > /* Start child processes if we can (call only once in parent!) */
272   int
273   in_rchild()
274   {
# Line 274 | Line 276 | in_rchild()
276  
277          while (nchild < nproc) {        /* fork until target reached */
278                  errno = 0;
279 <                rval = open_process(&kida[nchild].pr, NULL);
279 >                rval = open_process(&kidpr[nchild], NULL);
280                  if (rval < 0)
281                          error(SYSTEM, "open_process() call failed");
282                  if (rval == 0) {        /* if in child, set up & return true */
283 <                        lu_doall(&modconttab, set_stdout, NULL);
283 >                        lu_doall(&modconttab, &set_stdout, NULL);
284                          lu_done(&ofiletab);
285                          while (nchild--) {      /* don't share other pipes */
286 <                                close(kida[nchild].pr.w);
286 >                                close(kidpr[nchild].w);
287                                  fclose(kida[nchild].infp);
288                          }
289                          inpfmt = (sizeof(RREAL)==sizeof(double)) ? 'd' : 'f';
# Line 301 | Line 303 | in_rchild()
303                  if (rval != PIPE_BUF)
304                          error(CONSISTENCY, "bad value from open_process()");
305                                          /* connect to child's output */
306 <                kida[nchild].infp = fdopen(kida[nchild].pr.r, "rb");
306 >                kida[nchild].infp = fdopen(kidpr[nchild].r, "rb");
307                  if (kida[nchild].infp == NULL)
308                          error(SYSTEM, "out of memory in in_rchild()");
307 #ifdef getc_unlocked
308                flockfile(kida[nchild].infp);   /* avoid mutex overhead */
309 #endif
309                  kida[nchild++].nr = 0;  /* mark as available */
310          }
311 + #ifdef getc_unlocked
312 +        for (rval = nchild; rval--; )   /* avoid mutex overhead */
313 +                flockfile(kida[rval].infp);
314 + #endif
315          return(0);                      /* return "false" in parent */
316   }
317  
# Line 317 | Line 320 | in_rchild()
320   void
321   end_children(int immed)
322   {
323 <        int     status;
324 <        
325 <        while (nchild > 0) {
326 <                nchild--;
327 < #ifdef SIGKILL
325 <                if (immed)              /* error mode -- quick exit */
326 <                        kill(kida[nchild].pr.pid, SIGKILL);
323 >        int     i;
324 >
325 > #ifdef SIGKILL                          /* error mode -- quick exit */
326 >        for (i = nchild*immed; i-- > 0; )
327 >                kill(kidpr[nchild].pid, SIGKILL);
328   #endif
329 <                if ((status = close_process(&kida[nchild].pr)) > 0 && !immed) {
330 <                        sprintf(errmsg,
331 <                                "rendering process returned bad status (%d)",
331 <                                        status);
329 >        if ((i = close_processes(kidpr, nchild)) > 0 && !immed) {
330 >                sprintf(errmsg, "rendering process returned bad status (%d)",
331 >                                        i);
332                          error(WARNING, errmsg);
333                }
334                fclose(kida[nchild].infp);
333          }
334 +        while (nchild-- > 0)
335 +                fclose(kida[nchild].infp);
336   }
337  
338  
# Line 366 | Line 366 | tryagain:                              /* catch up with output? */
366          n = nr = 0;
367          for (i = nchild; i--; ) {
368                  if (kida[i].nr) {
369 <                        FD_SET(kida[i].pr.r, &readset);
369 >                        FD_SET(kidpr[i].r, &readset);
370                          ++nr;
371                  }
372 <                FD_SET(kida[i].pr.r, &errset);
373 <                if (kida[i].pr.r >= n)
374 <                        n = kida[i].pr.r + 1;
372 >                FD_SET(kidpr[i].r, &errset);
373 >                if (kidpr[i].r >= n)
374 >                        n = kidpr[i].r + 1;
375          }
376          if (!nr)                        /* nothing to wait for? */
377                  return(-1);
# Line 388 | Line 388 | tryagain:                              /* catch up with output? */
388                  FD_ZERO(&errset);
389          n = -1;                         /* read results from child(ren) */
390          for (i = nchild; i--; ) {
391 <                if (FD_ISSET(kida[i].pr.r, &errset))
391 >                if (FD_ISSET(kidpr[i].r, &errset))
392                          error(USER, "rendering process died");
393 <                if (FD_ISSET(kida[i].pr.r, &readset))
393 >                if (FD_ISSET(kidpr[i].r, &readset))
394                          queue_results(n = i);
395          }
396          return(n);                      /* first available child */
# Line 401 | Line 401 | tryagain:                              /* catch up with output? */
401   void
402   parental_loop()
403   {
404 <        static int      ignore_warning_given = 0;
405 <        int             qlimit = (accumulate == 1) ? 1 : MAXIQ-1;
404 >        const int       qlimit = (accumulate == 1) ? 1 : MAXIQ-1;
405          int             ninq = 0;
406          FVECT           orgdir[2*MAXIQ];
407          int             i, n;
# Line 411 | Line 410 | parental_loop()
410          flockfile(stdin);               /* avoid lock/unlock overhead */
411   #endif
412          while (getvec(orgdir[2*ninq]) == 0 && getvec(orgdir[2*ninq+1]) == 0) {
413 <                if (orgdir[2*ninq+1][0] == 0.0 &&       /* asking for flush? */
414 <                                (orgdir[2*ninq+1][1] == 0.0) &
415 <                                (orgdir[2*ninq+1][2] == 0.0)) {
416 <                        if (accumulate != 1) {
417 <                                if (!ignore_warning_given++)
418 <                                        error(WARNING,
420 <                                "dummy ray(s) ignored during accumulation\n");
421 <                                continue;
422 <                        }
423 <                        while (next_child_nq(1) >= 0)
424 <                                ;                       /* clear the queue */
425 <                        lastdone = lastray = 0;
426 <                        if ((yres <= 0) | (xres <= 0))
427 <                                waitflush = 1;          /* flush next */
428 <                        put_zero_record(++lastray);
429 <                } else if (++ninq >= qlimit ||
413 >                const int       zero_ray = orgdir[2*ninq+1][0] == 0.0 &&
414 >                                                (orgdir[2*ninq+1][1] == 0.0) &
415 >                                                (orgdir[2*ninq+1][2] == 0.0);
416 >                ninq += !zero_ray;
417 >                                /* Zero ray cannot go in input queue */
418 >                if (zero_ray ? ninq : ninq >= qlimit ||
419                              lastray/accumulate != (lastray+ninq)/accumulate) {
420                          i = next_child_nq(0);           /* manages output */
421                          n = ninq;
422 <                        if (accumulate != 1)            /* request flush? */
422 >                        if (accumulate > 1)             /* need terminator? */
423                                  memset(orgdir[2*n++], 0, sizeof(FVECT)*2);
424                          n *= sizeof(FVECT)*2;           /* send assignment */
425 <                        if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
425 >                        if (writebuf(kidpr[i].w, (char *)orgdir, n) != n)
426                                  error(SYSTEM, "pipe write error");
427                          kida[i].r1 = lastray+1;
428                          lastray += kida[i].nr = ninq;   /* mark as busy */
440                        ninq = 0;
429                          if (lastray < lastdone) {       /* RNUMBER wrapped? */
430                                  while (next_child_nq(1) >= 0)
431                                          ;
432 <                                lastdone = lastray = 0;
432 >                                lastray -= ninq;
433 >                                lastdone = lastray %= accumulate;
434                          }
435 +                        ninq = 0;
436                  }
437 +                if (zero_ray) {                         /* put bogus record? */
438 +                        if ((yres <= 0) | (xres <= 1) &&
439 +                                        (lastray+1) % accumulate == 0) {
440 +                                while (next_child_nq(1) >= 0)
441 +                                        ;               /* clear the queue */
442 +                                lastdone = lastray = accumulate-1;
443 +                                waitflush = 1;          /* flush next */
444 +                        }
445 +                        put_zero_record(++lastray);
446 +                }
447                  if (raysleft && !--raysleft)
448                          break;                          /* preemptive EOI */
449          }
# Line 475 | Line 475 | next_child_ready()
475          FD_ZERO(&writeset); FD_ZERO(&errset);
476          n = 0;
477          for (i = nchild; i--; ) {
478 <                FD_SET(kida[i].pr.w, &writeset);
479 <                FD_SET(kida[i].pr.r, &errset);
480 <                if (kida[i].pr.w >= n)
481 <                        n = kida[i].pr.w + 1;
482 <                if (kida[i].pr.r >= n)
483 <                        n = kida[i].pr.r + 1;
478 >                FD_SET(kidpr[i].w, &writeset);
479 >                FD_SET(kidpr[i].r, &errset);
480 >                if (kidpr[i].w >= n)
481 >                        n = kidpr[i].w + 1;
482 >                if (kidpr[i].r >= n)
483 >                        n = kidpr[i].r + 1;
484          }
485          errno = 0;
486          n = select(n, NULL, &writeset, &errset, NULL);
# Line 488 | Line 488 | next_child_ready()
488                  error(SYSTEM, "select() error in next_child_ready()");
489          n = -1;                         /* identify waiting child */
490          for (i = nchild; i--; ) {
491 <                if (FD_ISSET(kida[i].pr.r, &errset))
491 >                if (FD_ISSET(kidpr[i].r, &errset))
492                          error(USER, "rendering process died");
493 <                if (FD_ISSET(kida[i].pr.w, &writeset))
493 >                if (FD_ISSET(kidpr[i].w, &writeset))
494                          kida[n = i].nr = 0;
495          }
496          return(n);                      /* first available child */
# Line 521 | Line 521 | feeder_loop()
521                  if (++ninq >= MAXIQ) {
522                          i = next_child_ready();         /* get eager child */
523                          n = sizeof(FVECT)*2 * ninq;     /* give assignment */
524 <                        if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
524 >                        if (writebuf(kidpr[i].w, (char *)orgdir, n) != n)
525                                  error(SYSTEM, "pipe write error");
526                          kida[i].r1 = lastray+1;
527                          lastray += kida[i].nr = ninq;
528                        ninq = 0;
528                          if (lastray < lastdone)         /* RNUMBER wrapped? */
529                                  lastdone = lastray = 0;
530 +                        ninq = 0;
531                  }
532                  if (raysleft && !--raysleft)
533                          break;                          /* preemptive EOI */
# Line 535 | Line 535 | feeder_loop()
535          if (ninq) {                             /* polish off input */
536                  i = next_child_ready();
537                  n = sizeof(FVECT)*2 * ninq;
538 <                if (writebuf(kida[i].pr.w, (char *)orgdir, n) != n)
538 >                if (writebuf(kidpr[i].w, (char *)orgdir, n) != n)
539                          error(SYSTEM, "pipe write error");
540                  kida[i].r1 = lastray+1;
541                  lastray += kida[i].nr = ninq;
# Line 543 | Line 543 | feeder_loop()
543          }
544          memset(orgdir, 0, sizeof(FVECT)*2);     /* get results */
545          for (i = nchild; i--; ) {
546 <                writebuf(kida[i].pr.w, (char *)orgdir, sizeof(FVECT)*2);
546 >                writebuf(kidpr[i].w, (char *)orgdir, sizeof(FVECT)*2);
547                  queue_results(i);
548          }
549          if (recover)                            /* and from before? */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines