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, computing |
13 |
+ |
bins and the associated buffer growth, which can be crazy |
14 |
+ |
(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 summed bins. These will |
17 |
+ |
be queued and sorted by the parent for ordered output. |
18 |
+ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*/ |
19 |
+ |
|
20 |
|
#include "standard.h" |
21 |
|
#include <ctype.h> |
22 |
|
#include <signal.h> |
28 |
|
#include "lookup.h" |
29 |
|
#include "calcomp.h" |
30 |
|
|
31 |
+ |
#ifdef _WIN32 |
32 |
+ |
typedef int ssize_t; |
33 |
+ |
#endif |
34 |
+ |
|
35 |
|
#ifndef MAXMODLIST |
36 |
|
#define MAXMODLIST 1024 /* maximum modifiers we'll track */ |
37 |
|
#endif |
38 |
|
|
39 |
< |
size_t treebufsiz = BUFSIZ; /* current tree buffer size */ |
39 |
> |
ssize_t treebufsiz = BUFSIZ; /* current tree buffer size */ |
40 |
|
|
41 |
|
typedef double DCOLOR[3]; /* double-precision color */ |
42 |
|
|
185 |
|
void add_contrib(const char *modn); |
186 |
|
void done_contrib(int navg); |
187 |
|
|
188 |
+ |
#ifdef getc_unlocked /* avoid nasty overheads */ |
189 |
+ |
#undef getc |
190 |
+ |
#define getc getc_unlocked |
191 |
+ |
#undef putc |
192 |
+ |
#define putc putc_unlocked |
193 |
+ |
#undef ferror |
194 |
+ |
#define ferror ferror_unlocked |
195 |
+ |
static int |
196 |
+ |
fread_unl(void *ptr, int size, int nitems, FILE *fp) |
197 |
+ |
{ |
198 |
+ |
char *p = (char *)ptr; |
199 |
+ |
int len = size*nitems; |
200 |
+ |
while (len-- > 0) { |
201 |
+ |
int c = getc_unlocked(fp); |
202 |
+ |
if (c == EOF) |
203 |
+ |
return((p - (char *)ptr)/size); |
204 |
+ |
*p++ = c; |
205 |
+ |
} |
206 |
+ |
return(nitems); |
207 |
+ |
} |
208 |
+ |
#undef fread |
209 |
+ |
#define fread fread_unl |
210 |
+ |
static int |
211 |
+ |
fwrite_unl(const void *ptr, int size, int nitems, FILE *fp) |
212 |
+ |
{ |
213 |
+ |
const char *p = (const char *)ptr; |
214 |
+ |
int len = size*nitems; |
215 |
+ |
while (len-- > 0) |
216 |
+ |
putc_unlocked(*p++, fp); |
217 |
+ |
if (ferror_unlocked(fp)) |
218 |
+ |
return(0); |
219 |
+ |
return(nitems); |
220 |
+ |
} |
221 |
+ |
#undef fwrite |
222 |
+ |
#define fwrite fwrite_unl |
223 |
+ |
#endif |
224 |
+ |
|
225 |
|
/* return number of open rtrace processes */ |
226 |
|
static int |
227 |
|
nrtprocs(void) |
859 |
|
goto openerr; |
860 |
|
if (outfmt != 'a') |
861 |
|
SET_FILE_BINARY(sop->ofp); |
862 |
+ |
#ifdef getc_unlocked /* avoid lock/unlock overhead */ |
863 |
+ |
flockfile(sop->ofp); |
864 |
+ |
#endif |
865 |
|
if (header) { |
866 |
|
char info[512]; |
867 |
|
char *cp = info; |
927 |
|
return 0; /* dummy ray */ |
928 |
|
return strlen(buf); |
929 |
|
case 'f': |
930 |
< |
if (fread(buf, sizeof(float), 6, fp) < 6) |
930 |
> |
if (fread(buf, sizeof(float), 6, fp) != 6) |
931 |
|
return -1; |
932 |
|
fvp = (float *)buf + 3; |
933 |
|
if (DOT(fvp,fvp) <= FTINY*FTINY) |
934 |
|
return 0; /* dummy ray */ |
935 |
|
return sizeof(float)*6; |
936 |
|
case 'd': |
937 |
< |
if (fread(buf, sizeof(double), 6, fp) < 6) |
937 |
> |
if (fread(buf, sizeof(double), 6, fp) != 6) |
938 |
|
return -1; |
939 |
|
dvp = (double *)buf + 3; |
940 |
|
if (DOT(dvp,dvp) <= FTINY*FTINY) |
1173 |
|
} else if (rt->nbr + BUFSIZ > rt->bsiz) { |
1174 |
|
if (rt->bsiz + BUFSIZ <= treebufsiz) |
1175 |
|
rt->bsiz = treebufsiz; |
1176 |
< |
else |
1177 |
< |
treebufsiz = rt->bsiz += BUFSIZ; |
1176 |
> |
else if ((treebufsiz = rt->bsiz += BUFSIZ) < 0) |
1177 |
> |
error(INTERNAL, |
1178 |
> |
"ray buffer does not fit memory"); |
1179 |
|
rt->buf = (char *)realloc(rt->buf, rt->bsiz); |
1180 |
|
} |
1181 |
|
if (rt->buf == NULL) |
1182 |
|
error(SYSTEM, "out of memory in wait_rproc"); |
1183 |
< |
nr = read(rt->pd.r, rt->buf+rt->nbr, rt->bsiz-rt->nbr); |
1184 |
< |
if (nr <= 0) |
1183 |
> |
nr = rt->bsiz - rt->nbr; |
1184 |
> |
if (nr & ~0x7fffffff) /* avoid 32-bit OS issues */ |
1185 |
> |
nr = 0x7fffffff; |
1186 |
> |
nr = read(rt->pd.r, rt->buf+rt->nbr, nr); |
1187 |
> |
if (nr < 0) |
1188 |
> |
error(SYSTEM, "read error from rtrace"); |
1189 |
> |
if (!nr) |
1190 |
|
error(USER, "rtrace process died"); |
1191 |
|
rt->nbr += nr; /* advance & check */ |
1192 |
|
if (rt->nbr >= 6 && !memcmp(rt->buf+rt->nbr-6, |
1367 |
|
error(WARNING, errmsg); |
1368 |
|
break; |
1369 |
|
} |
1370 |
+ |
#ifdef getc_unlocked /* avoid lock/unlock overhead */ |
1371 |
+ |
flockfile(sout.ofp); |
1372 |
+ |
#endif |
1373 |
|
if (header && checkheader(sout.ofp, outvfmt, NULL) != 1) { |
1374 |
|
sprintf(errmsg, "format mismatch for '%s'", |
1375 |
|
oname); |