| 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> |
| 29 |
|
#include "calcomp.h" |
| 30 |
|
|
| 31 |
|
#ifdef _WIN32 |
| 32 |
< |
typedef long ssize_t; |
| 32 |
> |
typedef int ssize_t; |
| 33 |
|
#endif |
| 34 |
|
|
| 35 |
|
#ifndef MAXMODLIST |
| 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) |
| 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); |