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

Comparing src/rt/RcontribSimulManager.cpp (file contents):
Revision 2.13 by greg, Thu Oct 16 23:14:31 2025 UTC vs.
Revision 2.16 by greg, Thu Oct 23 01:26:48 2025 UTC

# Line 52 | Line 52 | struct RowAssignment {
52          uint32                  ac;             // accumulation count
53   };
54  
55 < // Get format identifier
56 < const char *
57 < formstr(int f)
58 < {
59 <        switch (f) {
60 <        case 'a': return("ascii");
61 <        case 'f': return("float");
62 <        case 'd': return("double");
63 <        case 'c': return(NCSAMP==3 ? COLRFMT : SPECFMT);
64 <        }
65 <        return("unknown");
66 < }
55 > static const char       ROW_DONE[] = "ROW FINISHED\n";
56  
57 < // Our default data share function
58 < RdataShare *
70 < defDataShare(const char *name, RCOutputOp op, size_t siz)
71 < {
72 <        return new RdataShareMap(name, RSDOflags[op], siz);
73 < }
74 <
75 < // Allocate rcontrib accumulator
76 < RcontribMod *
57 > // allocate rcontrib accumulator
58 > static RcontribMod *
59   NewRcMod(const char *prms, const char *binexpr, int ncbins)
60   {
61 +        if (binexpr && !*binexpr) binexpr = NULL;
62          if (!prms) prms = "";
63          if ((ncbins > 1) & !binexpr) {
64                  error(USER, "missing bin expression");
# Line 110 | Line 93 | NewRcMod(const char *prms, const char *binexpr, int nc
93          return mp;
94   }
95  
96 < // Free an RcontribMod
96 > // Free an RcontribMod (public for RcontribSimulManager constructor)
97   void
98   FreeRcMod(void *p)
99   {
# Line 120 | Line 103 | FreeRcMod(void *p)
103          efree(p);
104   }
105  
106 + // Get format identifier
107 + const char *
108 + formstr(int f)
109 + {
110 +        switch (f) {
111 +        case 'a': return("ascii");
112 +        case 'f': return("float");
113 +        case 'd': return("double");
114 +        case 'c': return(NCSAMP==3 ? COLRFMT : SPECFMT);
115 +        }
116 +        return("unknown");
117 + }
118 +
119 + // Our default data share function
120 + RdataShare *
121 + defDataShare(const char *name, RCOutputOp op, size_t siz)
122 + {
123 +        return new RdataShareMap(name, RSDOflags[op], siz);
124 + }
125 +
126   // Set output format ('f', 'd', or 'c')
127   bool
128   RcontribSimulManager::SetDataFormat(int ty)
# Line 625 | Line 628 | RcontribSimulManager::ComputeRecord(const FVECT orig_d
628                  return 0;
629          }
630          if (nkids > 0) {                        // in parent process?
631 <                int     k = GetChild();         // updates output rows
632 <                if (k < 0) return -1;           // can't really happen
631 >                int     k = GetChild(false);    // updates output rows
632 >                if (k < 0) return -1;           // someone died?
633                  RowAssignment   rass;
634                  rass.row = kidRow[k] = rInPos++;
635                  rass.ac = accum;
# Line 671 | Line 674 | RcontribSimulManager::GetChild(bool forceWait)
674                  return -1;
675                                                  // take inventory
676          int     pn, n = 0;
677 <        fd_set  writeset, errset;
678 <        FD_ZERO(&writeset); FD_ZERO(&errset);
677 >        fd_set  readset, errset;
678 >        FD_ZERO(&readset); FD_ZERO(&errset);
679          for (pn = nkids; pn--; ) {
680                  if (kidRow[pn] < 0) {           // child already ready?
681                          if (forceWait) continue;
682                          return pn;              // good enough
683                  }
684 <                FD_SET(kid[pn].w, &writeset);   // will check on this one
685 <                FD_SET(kid[pn].w, &errset);
686 <                if (kid[pn].w >= n)
687 <                        n = kid[pn].w + 1;
684 >                FD_SET(kid[pn].r, &readset);    // will check on this one
685 >                FD_SET(kid[pn].r, &errset);
686 >                if (kid[pn].r >= n)
687 >                        n = kid[pn].r + 1;
688          }
689          if (!n)                                 // every child is idle?
690                  return -1;
691                                                  // wait on "busy" child(ren)
692 <        while ((n = select(n, NULL, &writeset, &errset, NULL)) <= 0)
692 >        while ((n = select(n, &readset, NULL, &errset, NULL)) <= 0)
693                  if (errno != EINTR) {
694                          error(SYSTEM, "select call failed in GetChild()");
695                          return -1;
696                  }
697 +        char    buf[sizeof(ROW_DONE)] = "X";
698          pn = -1;                                // get flags set by select
699          for (n = nkids; n--; )
700                  if (kidRow[n] >= 0 &&
701 <                                FD_ISSET(kid[n].w, &writeset) |
702 <                                FD_ISSET(kid[n].w, &errset)) {
701 >                                FD_ISSET(kid[n].r, &readset) |
702 >                                FD_ISSET(kid[n].r, &errset)) {
703 >                                                // check for error
704 >                        if (FD_ISSET(kid[n].r, &errset) ||
705 >                                        read(kid[n].r, buf, sizeof(ROW_DONE)) <= 0 ||
706 >                                        memcmp(buf, ROW_DONE, sizeof(ROW_DONE)))
707 >                                return -1;
708                                                  // update output row counts
709 <                        if (!FD_ISSET(kid[n].w, &errset))
710 <                                UpdateRowsDone(kidRow[n]);
702 <                        kidRow[n] = -1;         // flag it available
709 >                        UpdateRowsDone(kidRow[n]);
710 >                        kidRow[n] = -1;         // flag child available
711                          pn = n;
712                  }
713          return pn;
# Line 750 | Line 758 | RcontribSimulManager::RunChild()
758  
759                  if (ComputeRecord(vecList) <= 0)
760                          exit(1);
761 +                                                // signal this row is done
762 +                if (write(1, ROW_DONE, sizeof(ROW_DONE)) != sizeof(ROW_DONE))
763 +                        exit(1);
764          }
765          if (nr) {
766                  error(SYSTEM, "read error in child process");
# Line 775 | Line 786 | RcontribSimulManager::StartKids(int n2go)
786          fflush(stdout);                         // shouldn't use, anyway
787          while (nkids < n2go) {
788                  kid[nkids] = sp_inactive;
778                kid[nkids].w = dup(1);
779                kid[nkids].flags |= PF_FILT_OUT;
789                  int     rv = open_process(&kid[nkids], NULL);
790                  if (!rv) {                      // in child process?
791 <                        while (nkids-- > 0)
791 >                        while (nkids-- > 0) {
792 >                                close(kid[nkids].r);
793                                  close(kid[nkids].w);
794 +                        }
795                          free(kid); free(kidRow);
796                          kid = NULL; kidRow = NULL;
797                          RunChild();             // should never return

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines