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.10 by greg, Sat Jun 16 17:09:49 2012 UTC vs.
Revision 2.20 by greg, Sun Aug 23 00:17:12 2015 UTC

# Line 6 | Line 6 | static const char RCSid[] = "$Id$";
6   * Controlling process for multiple children
7   */
8  
9 + #include <signal.h>
10   #include "rcontrib.h"
10 #include "platform.h"
11 #include "rtprocess.h"
11   #include "selcall.h"
12  
13   #define MAXIQ           (int)(PIPE_BUF/(sizeof(FVECT)*2))
# Line 266 | Line 265 | set_stdout(const LUENT *le, void *p)
265   }
266  
267  
268 < /* Start child processes if we can */
268 > /* Start child processes if we can (call only once in parent!) */
269   int
270   in_rchild()
271   {
# Line 278 | Line 277 | in_rchild()
277                  if (rval < 0)
278                          error(SYSTEM, "open_process() call failed");
279                  if (rval == 0) {        /* if in child, set up & return true */
280 <                        lu_doall(&modconttab, set_stdout, NULL);
280 >                        lu_doall(&modconttab, &set_stdout, NULL);
281                          lu_done(&ofiletab);
282                          while (nchild--) {      /* don't share other pipes */
283                                  close(kida[nchild].pr.w);
# Line 304 | Line 303 | in_rchild()
303                  kida[nchild].infp = fdopen(kida[nchild].pr.r, "rb");
304                  if (kida[nchild].infp == NULL)
305                          error(SYSTEM, "out of memory in in_rchild()");
307 #ifdef getc_unlocked
308                flockfile(kida[nchild].infp);   /* avoid mutex overhead */
309 #endif
306                  kida[nchild++].nr = 0;  /* mark as available */
307          }
308 + #ifdef getc_unlocked
309 +        for (rval = nchild; rval--; )   /* avoid mutex overhead */
310 +                flockfile(kida[rval].infp);
311 + #endif
312          return(0);                      /* return "false" in parent */
313   }
314  
315  
316   /* Close child processes */
317   void
318 < end_children()
318 > end_children(int immed)
319   {
320          int     status;
321          
322          while (nchild > 0) {
323                  nchild--;
324 <                if ((status = close_process(&kida[nchild].pr)) > 0) {
324 > #ifdef SIGKILL
325 >                if (immed)              /* error mode -- quick exit */
326 >                        kill(kida[nchild].pr.pid, SIGKILL);
327 > #endif
328 >                if ((status = close_process(&kida[nchild].pr)) > 0 && !immed) {
329                          sprintf(errmsg,
330                                  "rendering process returned bad status (%d)",
331                                          status);
# Line 397 | Line 401 | tryagain:                              /* catch up with output? */
401   void
402   parental_loop()
403   {
404 <        static int      ignore_warning_given = 0;
401 <        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 407 | 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,
416 <                                "dummy ray(s) ignored during accumulation\n");
417 <                                continue;
418 <                        }
419 <                        while (next_child_nq(1) >= 0)
420 <                                ;                       /* clear the queue */
421 <                        lastdone = lastray = 0;
422 <                        if ((yres <= 0) | (xres <= 0))
423 <                                waitflush = 1;          /* flush next */
424 <                        put_zero_record(++lastray);
425 <                } 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)
426                                  error(SYSTEM, "pipe write error");
427                          kida[i].r1 = lastray+1;
428                          lastray += kida[i].nr = ninq;   /* mark as busy */
436                        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 462 | Line 466 | static int
466   next_child_ready()
467   {
468          fd_set                  writeset, errset;
469 <        int                     i, n, nqr;
469 >        int                     i, n;
470  
471          for (i = nchild; i--; )         /* see if there's one free first */
472                  if (!kida[i].nr)
# Line 521 | Line 525 | feeder_loop()
525                                  error(SYSTEM, "pipe write error");
526                          kida[i].r1 = lastray+1;
527                          lastray += kida[i].nr = ninq;
524                        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 537 | Line 541 | feeder_loop()
541                  lastray += kida[i].nr = ninq;
542                  ninq = 0;
543          }
544 <        for (i = nchild; i--; ) {               /* get results */
545 <                close(kida[i].pr.w);
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);
547                  queue_results(i);
548          }
549          if (recover)                            /* and from before? */
550                  queue_modifiers();
551 <        end_children();                         /* free up file descriptors */
551 >        end_children(0);                        /* free up file descriptors */
552          for (i = 0; i < nmods; i++)
553                  mod_output(out_bq->mca[i]);     /* output accumulated record */
554          end_record();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines