--- ray/src/util/rtcontrib.c 2005/05/26 06:55:22 1.2 +++ ray/src/util/rtcontrib.c 2005/06/02 04:47:27 1.10 @@ -1,13 +1,13 @@ #ifndef lint -static const char RCSid[] = "$Id: rtcontrib.c,v 1.2 2005/05/26 06:55:22 greg Exp $"; +static const char RCSid[] = "$Id: rtcontrib.c,v 1.10 2005/06/02 04:47:27 greg Exp $"; #endif /* * Gather rtrace output to compute contributions from particular sources */ +#include "standard.h" #include -#include "rtio.h" -#include "rterror.h" +#include #include "platform.h" #include "rtprocess.h" #include "selcall.h" @@ -64,23 +64,21 @@ struct rtproc { int bsiz; /* ray tree buffer length */ char *buf; /* ray tree buffer */ int nbr; /* number of bytes from rtrace */ -}; /* rtrace process */ +}; /* rtrace process buffer */ /* rtrace command and defaults */ -char *rtargv[256] = { "rtrace", "-dt", "0", "-dj", ".5", "-dr", "3", - "-ab", "1", "-ad", "512", }; +char *rtargv[256] = { "rtrace", "-dj", ".5", "-dr", "3", + "-ab", "1", "-ad", "128", "-lr", "-10", }; int rtargc = 11; /* overriding rtrace options */ -char *myrtopts[] = { "-o~~TmWdp", "-h-", - "-x", "1", "-y", "0", - "-as", "0", "-aa", "0", NULL }; +char *myrtopts[] = { "-o~~TmWdp", "-h-", "-x", "1", "-y", "0", + "-dt", "0", "-as", "0", "-aa", "0", NULL }; struct rtproc rt0; /* head of rtrace process list */ struct rtproc *rt_unproc = NULL; /* unprocessed ray trees */ char persistfn[] = "pfXXXXXX"; /* persist file name */ -char fmt[8]; /* rtrace i/o format */ int gargc; /* global argc */ char **gargv; /* global argv */ @@ -108,12 +106,13 @@ int nmods = 0; /* number of modifiers */ MODCONT *addmodifier(char *modn, char *outf, char *binv); -int done_rprocs(struct rtproc *rtp); void init(int np); -void tracecontribs(FILE *fp); +int done_rprocs(struct rtproc *rtp); +void trace_contribs(FILE *fp); struct rtproc *wait_rproc(void); struct rtproc *get_rproc(void); -void process_rays(struct rtproc *rtp); +void queue_raytree(struct rtproc *rtp); +void process_queue(void); void putcontrib(const DCOLOR cnt, FILE *fout); void add_contrib(const char *modn); @@ -124,9 +123,11 @@ static void setformat(const char *fmt) { switch (fmt[0]) { - case 'a': case 'f': case 'd': + SET_FILE_BINARY(stdin); + /* fall through */ + case 'a': inpfmt = fmt[0]; break; default: @@ -159,6 +160,7 @@ main(int argc, char *argv[]) int nprocs = 1; char *curout = NULL; char *binval = NULL; + char fmt[8]; int i, j; /* global program name */ gargv = argv; @@ -188,18 +190,31 @@ main(int argc, char *argv[]) case '\0': header = !header; continue; - case '+': case '1': case 'T': case 't': + case '+': case '1': + case 'T': case 't': + case 'Y': case 'y': header = 1; continue; - case '-': case '0': case 'F': case 'f': + case '-': case '0': + case 'F': case 'f': + case 'N': case 'n': header = 0; continue; } break; case 'f': /* file or i/o format */ if (!argv[i][2]) { + char *fpath; if (i >= argc-1) break; - fcompile(argv[++i]); + fpath = getpath(argv[++i], + getrlibpath(), R_OK); + if (fpath == NULL) { + sprintf(errmsg, + "cannot find file '%s'", + argv[i]); + error(USER, errmsg); + } + fcompile(fpath); continue; } setformat(argv[i]+2); @@ -265,7 +280,8 @@ main(int argc, char *argv[]) execv(rtpath, rtargv); perror(rtpath); /* execv() should not return */ exit(1); - } else if (nprocs > 1) { /* add persist file if parallel */ + } + if (nprocs > 1) { /* add persist file if parallel */ rtargv[rtargc++] = "-PP"; rtargv[rtargc++] = mktemp(persistfn); } @@ -279,7 +295,7 @@ main(int argc, char *argv[]) rtargv[rtargc] = NULL; /* start rtrace & compute contributions */ init(nprocs); - tracecontribs(stdin); + trace_contribs(stdin); quit(0); } @@ -331,7 +347,7 @@ quit(int status) exit(status); /* flushes all output streams */ } -/* start rtrace and initialize buffers */ +/* start rtrace processes and initialize */ void init(int np) { @@ -345,7 +361,14 @@ init(int np) scompile("Dx=$1;Dy=$2;Dz=$3;", NULL, 0); scompile("Px=$4;Py=$5;Pz=$6;", NULL, 0); /* set up signal handling */ -#ifdef SIGPIPE /* not present on Windows */ + signal(SIGINT, quit); +#ifdef SIGHUP + signal(SIGHUP, quit); +#endif +#ifdef SIGTERM + signal(SIGTERM, quit); +#endif +#ifdef SIGPIPE signal(SIGPIPE, quit); #endif rtp = &rt0; /* start rtrace process(es) */ @@ -477,8 +500,12 @@ getofile(const char *ospec, const char *mname, int bn) LUENT *lep; if (ospec == NULL) { /* use stdout? */ - if (!using_stdout && header) - printheader(stdout); + if (!using_stdout) { + if (outfmt != 'a') + SET_FILE_BINARY(stdout); + if (header) + printheader(stdout); + } using_stdout = 1; return stdout; } @@ -520,12 +547,18 @@ getofile(const char *ospec, const char *mname, int bn) if (lep->key == NULL) /* new entry */ lep->key = strcpy((char *)malloc(strlen(ofname)+1), ofname); if (lep->data == NULL) { /* open output file */ - FILE *fp = fopen(ofname, "w"); + FILE *fp; int i; + if (ofname[0] == '!') /* output to command */ + fp = popen(ofname+1, "w"); + else + fp = fopen(ofname, "w"); if (fp == NULL) { sprintf(errmsg, "cannot open '%s' for writing", ofname); error(SYSTEM, errmsg); } + if (outfmt != 'a') + SET_FILE_BINARY(fp); if (header) printheader(fp); /* play catch-up */ @@ -550,10 +583,21 @@ badspec: int getinp(char *buf, FILE *fp) { + char *cp; + int i; + switch (inpfmt) { case 'a': - if (fgets(buf, 128, fp) == NULL) - return 0; + cp = buf; /* make sure we get 6 floats */ + for (i = 0; i < 6; i++) { + if (fgetword(cp, buf+127-cp, fp) == NULL) + return 0; + if ((cp = fskip(cp)) == NULL || *cp) + return 0; + *cp++ = ' '; + } + getc(fp); /* get/put eol */ + *cp-- = '\0'; *cp = '\n'; return strlen(buf); case 'f': if (fread(buf, sizeof(float), 6, fp) < 6) @@ -679,16 +723,42 @@ done_contrib(void) } } -/* process (or save) ray tree produced by rtrace process */ +/* queue completed ray tree produced by rtrace process */ void -process_rays(struct rtproc *rtp) +queue_raytree(struct rtproc *rtp) { - struct rtproc *rtu; - /* check if time to process it */ - if (rtp->raynum == lastdone+1) { + struct rtproc *rtu, *rtl = NULL; + /* insert following ray order */ + for (rtu = rt_unproc; rtu != NULL; rtu = (rtl=rtu)->next) + if (rtp->raynum < rtu->raynum) + break; + rtu = (struct rtproc *)malloc(sizeof(struct rtproc)); + if (rtu == NULL) + error(SYSTEM, "out of memory in queue_raytree"); + *rtu = *rtp; + if (rtl == NULL) { + rtu->next = rt_unproc; + rt_unproc = rtu; + } else { + rtu->next = rtl->next; + rtl->next = rtu; + } + rtp->raynum = 0; /* clear path for next ray tree */ + rtp->bsiz = 0; + rtp->buf = NULL; + rtp->nbr = 0; +} + +/* process completed ray trees from our queue */ +void +process_queue(void) +{ + char modname[128]; + /* ray-ordered queue */ + while (rt_unproc != NULL && rt_unproc->raynum == lastdone+1) { + struct rtproc *rtp = rt_unproc; int n = rtp->nbr; const char *cp = rtp->buf; - char modname[128]; while (n > 0) { /* process rays */ register char *mnp = modname; /* skip leading tabs */ @@ -712,34 +782,10 @@ process_rays(struct rtproc *rtp) } done_contrib(); /* sum up contributions & output */ lastdone = rtp->raynum; - free(rtp->buf); - /* catch up with unprocessed list */ - while (rt_unproc != NULL && rt_unproc->raynum == lastdone+1) { - process_rays(rt_unproc); - rt_unproc = (rtu=rt_unproc)->next; - free(rtu); - } - } else { /* else insert in unprocessed list */ - struct rtproc *rtl = NULL; - for (rtu = rt_unproc; rtu != NULL; rtu = (rtl=rtu)->next) - if (rtp->raynum < rtu->raynum) - break; - rtu = (struct rtproc *)malloc(sizeof(struct rtproc)); - if (rtu == NULL) - error(SYSTEM, "out of memory in process_rays"); - *rtu = *rtp; - if (rtl == NULL) { - rtu->next = rt_unproc; - rt_unproc = rtu; - } else { - rtu->next = rtl->next; - rtl->next = rtu; - } + free(rtp->buf); /* free up buffer space */ + rt_unproc = rtp->next; + free(rtp); /* done with this ray tree */ } - rtp->raynum = 0; /* clear path for next ray tree */ - rtp->bsiz = 0; - rtp->buf = NULL; - rtp->nbr = 0; } /* wait for rtrace process to finish with ray tree */ @@ -796,7 +842,7 @@ wait_rproc(void) if (rt->nbr >= 4 && !memcmp(rt->buf+rt->nbr-4, "~\t~\t", 4)) { rt->nbr -= 4; /* elide terminator */ - process_rays(rt); + queue_raytree(rt); rtfree = rt; /* ready for next ray */ } } @@ -818,7 +864,7 @@ get_rproc(void) /* trace ray contributions (main loop) */ void -tracecontribs(FILE *fin) +trace_contribs(FILE *fin) { char inpbuf[128]; int iblen; @@ -827,17 +873,18 @@ tracecontribs(FILE *fin) while ((iblen = getinp(inpbuf, fin)) > 0) { if (lastray+1 < lastray) { /* counter rollover? */ while (wait_rproc() != NULL) - ; + process_queue(); lastdone = lastray = 0; } rtp = get_rproc(); /* get avail. rtrace process */ - rtp->raynum = ++lastray; /* assign this ray to it */ + rtp->raynum = ++lastray; /* assign ray to it */ writebuf(rtp->pd.w, inpbuf, iblen); if (!--raysleft) - break; /* explicit EOF */ + break; + process_queue(); /* catch up with results */ } while (wait_rproc() != NULL) /* process outstanding rays */ - ; + process_queue(); if (raysleft > 0) error(USER, "unexpected EOF on input"); }