5 |
|
* Gather rtrace output to compute contributions from particular sources |
6 |
|
*/ |
7 |
|
|
8 |
+ |
/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |
9 |
+ |
Need to refactor code by forking a subprocess for each |
10 |
+ |
rtrace call to take output and accumulate it into bins |
11 |
+ |
for the parent process. This will avoid our current |
12 |
+ |
bottleneck around processing output queues. We'll sum into |
13 |
+ |
bins and avoid the associated buffer growth, which can be crazy |
14 |
+ |
now (gigabytes/subprocess). Each child process will return |
15 |
+ |
a ray number and a fully computed and ready-to-output |
16 |
+ |
record of modifiers and their bin totals. These will |
17 |
+ |
be queued and sorted by the parent for ordered output or |
18 |
+ |
accumulated for all rays if -c 0 is in play. |
19 |
+ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ |
20 |
+ |
|
21 |
|
#include "standard.h" |
22 |
|
#include <ctype.h> |
23 |
|
#include <signal.h> |
37 |
|
#define MAXMODLIST 1024 /* maximum modifiers we'll track */ |
38 |
|
#endif |
39 |
|
|
40 |
+ |
#ifndef RNUMBER |
41 |
+ |
#define RNUMBER unsigned long /* ray counter (>= sizeof pointer) */ |
42 |
+ |
#endif |
43 |
+ |
|
44 |
|
ssize_t treebufsiz = BUFSIZ; /* current tree buffer size */ |
45 |
|
|
46 |
|
typedef double DCOLOR[3]; /* double-precision color */ |
112 |
|
struct rtproc { |
113 |
|
struct rtproc *next; /* next in list of processes */ |
114 |
|
SUBPROC pd; /* rtrace pipe descriptors */ |
115 |
< |
unsigned long raynum; /* ray number for this tree */ |
115 |
> |
RNUMBER raynum; /* ray number for this tree */ |
116 |
|
size_t bsiz; /* ray tree buffer length */ |
117 |
|
char *buf; /* ray tree buffer */ |
118 |
|
size_t nbr; /* number of bytes from rtrace */ |
159 |
|
int yres = 0; /* vert. output resolution */ |
160 |
|
|
161 |
|
int account; /* current accumulation count */ |
162 |
< |
unsigned long raysleft; /* number of rays left to trace */ |
162 |
> |
RNUMBER raysleft; /* number of rays left to trace */ |
163 |
|
long waitflush; /* how long until next flush */ |
164 |
|
|
165 |
< |
unsigned long lastray = 0; /* last ray number sent */ |
166 |
< |
unsigned long lastdone = 0; /* last ray processed */ |
165 |
> |
RNUMBER lastray = 0; /* last ray number sent */ |
166 |
> |
RNUMBER lastdone = 0; /* last ray processed */ |
167 |
|
|
168 |
|
int using_stdout = 0; /* are we using stdout? */ |
169 |
|
|
190 |
|
void add_contrib(const char *modn); |
191 |
|
void done_contrib(int navg); |
192 |
|
|
193 |
+ |
#ifdef getc_unlocked /* avoid nasty overheads */ |
194 |
+ |
#undef getc |
195 |
+ |
#define getc getc_unlocked |
196 |
+ |
#undef putc |
197 |
+ |
#define putc putc_unlocked |
198 |
+ |
#undef ferror |
199 |
+ |
#define ferror ferror_unlocked |
200 |
+ |
static int |
201 |
+ |
fread_unl(void *ptr, int size, int nitems, FILE *fp) |
202 |
+ |
{ |
203 |
+ |
char *p = (char *)ptr; |
204 |
+ |
int len = size*nitems; |
205 |
+ |
while (len-- > 0) { |
206 |
+ |
int c = getc_unlocked(fp); |
207 |
+ |
if (c == EOF) |
208 |
+ |
return((p - (char *)ptr)/size); |
209 |
+ |
*p++ = c; |
210 |
+ |
} |
211 |
+ |
return(nitems); |
212 |
+ |
} |
213 |
+ |
#undef fread |
214 |
+ |
#define fread fread_unl |
215 |
+ |
static int |
216 |
+ |
fwrite_unl(const void *ptr, int size, int nitems, FILE *fp) |
217 |
+ |
{ |
218 |
+ |
const char *p = (const char *)ptr; |
219 |
+ |
int len = size*nitems; |
220 |
+ |
while (len-- > 0) |
221 |
+ |
putc_unlocked(*p++, fp); |
222 |
+ |
if (ferror_unlocked(fp)) |
223 |
+ |
return(0); |
224 |
+ |
return(nitems); |
225 |
+ |
} |
226 |
+ |
#undef fwrite |
227 |
+ |
#define fwrite fwrite_unl |
228 |
+ |
#endif |
229 |
+ |
|
230 |
|
/* return number of open rtrace processes */ |
231 |
|
static int |
232 |
|
nrtprocs(void) |
596 |
|
rtp->next = NULL; /* terminate list */ |
597 |
|
if (yres > 0) { |
598 |
|
if (xres > 0) |
599 |
< |
raysleft = (unsigned long)xres*yres; |
599 |
> |
raysleft = (RNUMBER)xres*yres; |
600 |
|
else |
601 |
|
raysleft = yres; |
602 |
|
} else |
864 |
|
goto openerr; |
865 |
|
if (outfmt != 'a') |
866 |
|
SET_FILE_BINARY(sop->ofp); |
867 |
+ |
#ifdef getc_unlocked /* avoid lock/unlock overhead */ |
868 |
+ |
flockfile(sop->ofp); |
869 |
+ |
#endif |
870 |
|
if (header) { |
871 |
|
char info[512]; |
872 |
|
char *cp = info; |
932 |
|
return 0; /* dummy ray */ |
933 |
|
return strlen(buf); |
934 |
|
case 'f': |
935 |
< |
if (fread(buf, sizeof(float), 6, fp) < 6) |
935 |
> |
if (fread(buf, sizeof(float), 6, fp) != 6) |
936 |
|
return -1; |
937 |
|
fvp = (float *)buf + 3; |
938 |
|
if (DOT(fvp,fvp) <= FTINY*FTINY) |
939 |
|
return 0; /* dummy ray */ |
940 |
|
return sizeof(float)*6; |
941 |
|
case 'd': |
942 |
< |
if (fread(buf, sizeof(double), 6, fp) < 6) |
942 |
> |
if (fread(buf, sizeof(double), 6, fp) != 6) |
943 |
|
return -1; |
944 |
|
dvp = (double *)buf + 3; |
945 |
|
if (DOT(dvp,dvp) <= FTINY*FTINY) |
1372 |
|
error(WARNING, errmsg); |
1373 |
|
break; |
1374 |
|
} |
1375 |
+ |
#ifdef getc_unlocked /* avoid lock/unlock overhead */ |
1376 |
+ |
flockfile(sout.ofp); |
1377 |
+ |
#endif |
1378 |
|
if (header && checkheader(sout.ofp, outvfmt, NULL) != 1) { |
1379 |
|
sprintf(errmsg, "format mismatch for '%s'", |
1380 |
|
oname); |
1571 |
|
for (nvals = 0; nvals < lastout; nvals++) |
1572 |
|
if (getinp(oname, fin) < 0) |
1573 |
|
error(USER, "unexpected EOF on input"); |
1574 |
< |
lastray = lastdone = (unsigned long)lastout * accumulate; |
1574 |
> |
lastray = lastdone = (RNUMBER)lastout * accumulate; |
1575 |
|
if (raysleft) |
1576 |
|
raysleft -= lastray; |
1577 |
|
} |