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

Comparing ray/src/rt/RcontribSimulManager.cpp (file contents):
Revision 2.11 by greg, Thu Jan 2 16:16:49 2025 UTC vs.
Revision 2.19 by greg, Sat Oct 25 03:30:35 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 + // Standard file data share function
120 + RdataShare *
121 + fileDataShare(const char *name, RCOutputOp op, size_t siz)
122 + {
123 +        if (op == RCOrecover && access(name, R_OK|W_OK) < 0) {
124 +                sprintf(errmsg, "cannot recover from '%s'", name);
125 +                error(SYSTEM, errmsg);
126 +                return NULL;
127 +        }
128 +        return new RdataShareFile(name, RSDOflags[op], siz);
129 + }
130 +
131 + // Memory-mapped data share function
132 + RdataShare *
133 + mapDataShare(const char *name, RCOutputOp op, size_t siz)
134 + {
135 +        if (op == RCOrecover && access(name, R_OK|W_OK) < 0) {
136 +                sprintf(errmsg, "cannot recover from '%s'", name);
137 +                error(SYSTEM, errmsg);
138 +                return NULL;
139 +        }
140 +        return new RdataShareMap(name, RSDOflags[op], siz);
141 + }
142 +
143   // Set output format ('f', 'd', or 'c')
144   bool
145   RcontribSimulManager::SetDataFormat(int ty)
# Line 215 | Line 235 | RcontribSimulManager::AddModifier(const char *modn, co
235                  error(WARNING, "ignoring bad call to AddModifier()");
236                  return false;
237          }
238 +        if (*outspec == '!') {
239 +                error(USER, "command output not supported by RcontribSimulManager");
240 +                return false;
241 +        }
242          if (!nChan) {                           // initial call?
243                  if ((xres < 0) | (yres <= 0)) {
244                          error(USER, "xres, yres must be set before first modifier");
# Line 373 | Line 397 | RcontribSimulManager::PrepOutput()
397                          if (rd < 0)
398                                  return -1;
399                          if (rd >= op->nRows) {
400 <                                if (remWarnings >= 0) {
400 >                                if (remWarnings > 0) {
401                                          sprintf(errmsg, "recovered output '%s' is complete",
402                                                          op->GetName());
403                                          error(WARNING, --remWarnings ? errmsg : "etc...");
# Line 390 | Line 414 | RcontribSimulManager::PrepOutput()
414          }
415          rowsDone.NewBitMap(outList->nRows);     // create row completion map
416          rowsDone.ClearBits(0, rInPos, true);
417 <        return rInPos;
417 >        return nrDone = rInPos;
418   }
419  
420   // Create header in open write-only channel
# Line 510 | Line 534 | RcontribOutput::CheckHeader(const RcontribSimulManager
534                  return -1;
535          }
536                                                  // check #columns
537 <        if (((cp = findArgs(hdr, "NCOLS=", begData)) && atoi(cp)*esiz != rowBytes) ||
538 <                        !rcp->xres | (rowBytes > esiz)) {
539 <                sprintf(errmsg, "expected NCOLS=%d in '%s'",
516 <                                int(rowBytes/esiz), GetName());
537 >        if ((cp = findArgs(hdr, "NCOLS=", begData)) ? (atoi(cp)*esiz != rowBytes)
538 >                                                    : (!rcp->xres | (rowBytes > esiz))) {
539 >                sprintf(errmsg, "expected NCOLS=%d in '%s'", int(rowBytes/esiz), GetName());
540                  error(USER, errmsg);
541                  return -1;
542          }
# Line 555 | Line 578 | RcontribSimulManager::ResetRow(int r)
578                          return false;
579  
580          rowsDone.ClearBits(r, rInPos-r, false);
581 <        rInPos = r;
581 >        nrDone = rInPos = r;
582          return true;
583   }
584  
# Line 602 | Line 625 | putModContrib(const LUENT *lp, void *p)
625                  }
626                  } break;
627          default:
628 <                error(CONSISTENCY, "unsupported output type in sendModContrib()");
628 >                error(CONSISTENCY, "unsupported output type in putModContrib()");
629                  return -1;
630          }
631                                                  // clear for next tally
# Line 621 | Line 644 | RcontribSimulManager::ComputeRecord(const FVECT orig_d
644                  return 0;
645          }
646          if (nkids > 0) {                        // in parent process?
647 <                int     k = GetChild();         // updates output rows
648 <                if (k < 0) return -1;           // can't really happen
647 >                int     k = GetChild(false);    // updates output rows
648 >                if (k < 0) return -1;           // someone died?
649                  RowAssignment   rass;
650                  rass.row = kidRow[k] = rInPos++;
651                  rass.ac = accum;
# Line 667 | Line 690 | RcontribSimulManager::GetChild(bool forceWait)
690                  return -1;
691                                                  // take inventory
692          int     pn, n = 0;
693 <        fd_set  writeset, errset;
694 <        FD_ZERO(&writeset); FD_ZERO(&errset);
693 >        fd_set  readset, errset;
694 >        FD_ZERO(&readset); FD_ZERO(&errset);
695          for (pn = nkids; pn--; ) {
696                  if (kidRow[pn] < 0) {           // child already ready?
697                          if (forceWait) continue;
698                          return pn;              // good enough
699                  }
700 <                FD_SET(kid[pn].w, &writeset);   // will check on this one
701 <                FD_SET(kid[pn].w, &errset);
702 <                if (kid[pn].w >= n)
703 <                        n = kid[pn].w + 1;
700 >                FD_SET(kid[pn].r, &readset);    // will check on this one
701 >                FD_SET(kid[pn].r, &errset);
702 >                if (kid[pn].r >= n)
703 >                        n = kid[pn].r + 1;
704          }
705          if (!n)                                 // every child is idle?
706                  return -1;
707                                                  // wait on "busy" child(ren)
708 <        while ((n = select(n, NULL, &writeset, &errset, NULL)) <= 0)
708 >        while ((n = select(n, &readset, NULL, &errset, NULL)) <= 0)
709                  if (errno != EINTR) {
710                          error(SYSTEM, "select call failed in GetChild()");
711                          return -1;
712                  }
713 +        char    buf[sizeof(ROW_DONE)] = "X";
714          pn = -1;                                // get flags set by select
715          for (n = nkids; n--; )
716                  if (kidRow[n] >= 0 &&
717 <                                FD_ISSET(kid[n].w, &writeset) |
718 <                                FD_ISSET(kid[n].w, &errset)) {
717 >                                FD_ISSET(kid[n].r, &readset) |
718 >                                FD_ISSET(kid[n].r, &errset)) {
719 >                                                // check for error
720 >                        if (FD_ISSET(kid[n].r, &errset) ||
721 >                                        read(kid[n].r, buf, sizeof(ROW_DONE)) <= 0 ||
722 >                                        memcmp(buf, ROW_DONE, sizeof(ROW_DONE)))
723 >                                return -1;
724                                                  // update output row counts
725 <                        if (!FD_ISSET(kid[n].w, &errset))
726 <                                UpdateRowsDone(kidRow[n]);
698 <                        kidRow[n] = -1;         // flag it available
725 >                        UpdateRowsDone(kidRow[n]);
726 >                        kidRow[n] = -1;         // flag child available
727                          pn = n;
728                  }
729          return pn;
# Line 709 | Line 737 | RcontribSimulManager::UpdateRowsDone(int r)
737                  error(WARNING, "redundant call to UpdateRowsDone()");
738                  return false;
739          }
740 <        int     nDone = GetRowFinished();
741 <        if (nDone <= r)
740 >        GetRowFinished();
741 >        if (nrDone <= r)
742                  return true;                    // nothing to update, yet
743          for (RcontribOutput *op = outList; op; op = op->next)
744 <                if (!op->SetRowsDone(nDone))
744 >                if (!op->SetRowsDone(nrDone))
745                          return false;
746          return true;                            // up-to-date
747   }
# Line 733 | Line 761 | RcontribSimulManager::RunChild()
761                          error(CONSISTENCY, "bad accumulator count in child");
762                          exit(1);
763                  }
764 <                if (rass.ac > accum)
765 <                        vecList = (FVECT *)erealloc(vecList,
766 <                                                sizeof(FVECT)*2*rass.ac);
764 >                if (rass.ac > accum) {
765 >                        efree(vecList);
766 >                        vecList = (FVECT *)emalloc(sizeof(FVECT)*2*rass.ac);
767 >                }
768                  accum = rass.ac;
769                  rInPos = rass.row;
770  
# Line 745 | Line 774 | RcontribSimulManager::RunChild()
774  
775                  if (ComputeRecord(vecList) <= 0)
776                          exit(1);
777 +                                                // signal this row is done
778 +                if (write(1, ROW_DONE, sizeof(ROW_DONE)) != sizeof(ROW_DONE))
779 +                        exit(1);
780          }
781          if (nr) {
782                  error(SYSTEM, "read error in child process");
# Line 770 | Line 802 | RcontribSimulManager::StartKids(int n2go)
802          fflush(stdout);                         // shouldn't use, anyway
803          while (nkids < n2go) {
804                  kid[nkids] = sp_inactive;
773                kid[nkids].w = dup(1);
774                kid[nkids].flags |= PF_FILT_OUT;
805                  int     rv = open_process(&kid[nkids], NULL);
806                  if (!rv) {                      // in child process?
807 <                        while (nkids-- > 0)
807 >                        while (nkids-- > 0) {
808 >                                close(kid[nkids].r);
809                                  close(kid[nkids].w);
810 +                        }
811                          free(kid); free(kidRow);
812                          kid = NULL; kidRow = NULL;
813                          RunChild();             // should never return

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)