Back to index

radiance  4R0+20100331
Defines | Functions | Variables
rholo.c File Reference
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <sys/stat.h>
#include <string.h>
#include "platform.h"
#include "rterror.h"
#include "resolu.h"
#include "rholo.h"
#include "random.h"

Go to the source code of this file.

Defines

#define FRAGWARN   20 /* fragmentation for warning (%) */
#define MAXQTIME   3 /* target maximum seconds in queue */
#define RTFLUSH   (300/MAXQTIME*totqlen) /* <= 5 minutes */

Functions

static void onsig (int signo)
static void sigdie (int signo, char *msg)
static int resfmode (int fd, int mod)
static void initrholo (void)
static int rholo (void)
static void setdefaults (HDGRID *gp)
static void creatholo (HDGRID *gp)
static void loadholo (void)
static void rootname (char *rn, char *fn)
static void badvalue (int vc)
int main (int argc, char *argv[])
static void setdefaults (register HDGRID *gp)
static int headline (char *s, void *p)
void done_packets (PACKET *pl)
static void rootname (register char *rn, register char *fn)
void eputs (char *s)
void quit (int ec)

Variables

static const char RCSid [] = "$Id: rholo.c,v 3.74 2008/12/05 00:22:33 greg Exp $"
int NVARS = NRHVARS
VARIABLE vv [] = RHVINIT
char * progname
char * hdkfile
char froot [256]
int ncprocs = 0
char * outdev = NULL
int readinp = 0
int force = 0
time_t starttime
time_t endtime
time_t reporttime
off_t maxdisk
int rtargc = 1
char * rtargv [128] = {"rtrace", NULL}
int orig_mode = -1
long nraysdone = 0L
long npacksdone = 0L
PACKETfreepacks
int totqlen
char * sigerr [NSIG]
int nowarn
static gethfunc headline

Define Documentation

#define FRAGWARN   20 /* fragmentation for warning (%) */

Definition at line 21 of file rholo.c.

#define MAXQTIME   3 /* target maximum seconds in queue */

Definition at line 24 of file rholo.c.

#define RTFLUSH   (300/MAXQTIME*totqlen) /* <= 5 minutes */

Definition at line 29 of file rholo.c.


Function Documentation

static void badvalue ( int  vc) [static]

Definition at line 624 of file rholo.c.

{
       sprintf(errmsg, "bad value for variable '%s'", vnam(vc));
       error(USER, errmsg);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void creatholo ( HDGRID gp) [static]

Definition at line 451 of file rholo.c.

{
       extern char   VersionID[];
       int32  lastloc, nextloc;
       int    n;
       int    fd;
       FILE   *fp;
                                   /* open & truncate file */
       if ((fp = fopen(hdkfile, "w+")) == NULL) {
              sprintf(errmsg, "cannot open \"%s\" for writing", hdkfile);
              error(SYSTEM, errmsg);
       }
                                   /* write information header */
       newheader("RADIANCE", fp);
       fprintf(fp, "SOFTWARE= %s\n", VersionID);
       printvars(fp);
       fputformat(HOLOFMT, fp);
       fputc('\n', fp);
       putw(HOLOMAGIC, fp);        /* put magic number */
       fd = dup(fileno(fp));
       fclose(fp);                 /* flush and close stdio stream */
       lastloc = lseek(fd, (off_t)0, SEEK_END);
       for (n = vdef(SECTION); n--; gp++) {      /* initialize each section */
              nextloc = 0L;
              write(fd, (char *)&nextloc, sizeof(nextloc));
              hdinit(fd, gp);                    /* writes beam index */
              if (!n)
                     break;
              nextloc = hdfilen(fd);             /* write section pointer */
              if (lseek(fd, (off_t)lastloc, SEEK_SET) < 0)
                     error(SYSTEM,
                            "cannot seek on holodeck file in creatholo");
              write(fd, (char *)&nextloc, sizeof(nextloc));
              lseek(fd, (off_t)(lastloc=nextloc), SEEK_SET);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void done_packets ( PACKET pl)

Definition at line 570 of file rholo.c.

{
       static int    n2flush = 0;
       register PACKET      *p;

       while (pl != NULL) {
              p = pl; pl = p->next; p->next = NULL;
              if (p->nr > 0) {            /* add to holodeck */
                     memcpy( (void *)hdnewrays(hdlist[p->hd],p->bi,p->nr),
                            (void *)p->ra,
                            p->nr*sizeof(RAYVAL));
                     if (outdev != NULL)  /* display it */
                            disp_packet((PACKHEAD *)p);
                     if (hdcachesize <= 0)
                            n2flush++;
                     nraysdone += p->nr;
                     npacksdone++;
                     p->nr = 0;
              }
              p->next = freepacks;        /* push onto free list */
              freepacks = p;
       }
       if (n2flush >= RTFLUSH) {
              if (outdev != NULL)
                     hdsync(NULL, 1);
              else
                     hdflush(NULL);
              n2flush = 0;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void eputs ( char *  s)

Definition at line 634 of file rholo.c.

{
       static int  midline = 0;

       if (!*s)
              return;
       if (!midline++) {    /* prepend line with program name */
              fputs(progname, stderr);
              fputs(": ", stderr);
       }
       fputs(s, stderr);
       if (s[strlen(s)-1] == '\n') {
              fflush(stderr);
              midline = 0;
       }
}
static int headline ( char *  s,
void *  p 
) [static]

Definition at line 492 of file rholo.c.

{
       extern char   FMTSTR[];
       register char *cp;
       char   fmt[32];

       if (formatval(fmt, s)) {
              if (strcmp(fmt, HOLOFMT)) {
                     sprintf(errmsg, "%s file \"%s\" has %s%s",
                                   HOLOFMT, hdkfile, FMTSTR, fmt);
                     error(USER, errmsg);
              }
              return(0);
       }
       for (cp = s; *cp; cp++)            /* take off any comments */
              if (*cp == '#') {
                     *cp = '\0';
                     break;
              }
       setvariable(s, matchvar);   /* don't flag errors */
       return(0);
}

Here is the call graph for this function:

static void initrholo ( void  ) [static]

Definition at line 230 of file rholo.c.

{
       extern int    global_packet();
       register int  i;
                                          /* close holodeck on exec() */
       fcntl(hdlist[0]->fd, F_SETFD, FD_CLOEXEC);

       if (outdev != NULL)                /* open output device */
              disp_open(outdev);
       else if (ncprocs > 0)                     /* else use global ray feed */
              init_global();
                                          /* record disk space limit */
       if (!vdef(DISKSPACE))
              maxdisk = ((off_t)1<<(sizeof(off_t)*8-2)) - 1024;
       else
              maxdisk = 1024.*1024.*vflt(DISKSPACE);
                                          /* set up memory cache */
       if (outdev == NULL)
              hdcachesize = 0;            /* manual flushing */
       else if (vdef(CACHE))
              hdcachesize = 1024.*1024.*vflt(CACHE);
                                          /* open report file */
       if (vdef(REPORT)) {
              register char *s = sskip2(vval(REPORT), 1);
              if (*s && freopen(s, "a", stderr) == NULL)
                     quit(2);
       }
                                          /* mark the starting time */
       starttime = time(NULL);
                                          /* compute end time */
       if (!vdef(TIME) || vflt(TIME) <= FTINY)
              endtime = 0;
       else
              endtime = starttime + vflt(TIME)*3600. + .5;
                                          /* start rtrace */
       if (ncprocs > 0) {
              totqlen = i = start_rtrace();
              if (i < 1)
                     error(USER, "cannot start rtrace process(es)");
              if (vdef(REPORT)) {         /* make first report */
                     printargs(rtargc, rtargv, stderr);
                     report(0);
              }
                                          /* allocate packets */
              freepacks = (PACKET *)bmalloc(i*sizeof(PACKET));
              if (freepacks == NULL)
                     goto memerr;
              freepacks[--i].nr = 0;
              freepacks[i].next = NULL;
              if (!vdef(OBSTRUCTIONS) || !vbool(OBSTRUCTIONS)) {
                     freepacks[i].offset = (float *)bmalloc(
                                   RPACKSIZ*sizeof(float)*(i+1) );
                     if (freepacks[i].offset == NULL)
                            goto memerr;
              } else
                     freepacks[i].offset = NULL;
              while (i--) {
                     freepacks[i].nr = 0;
                     freepacks[i].offset = freepacks[i+1].offset == NULL ?
                                   NULL : freepacks[i+1].offset+RPACKSIZ ;
                     freepacks[i].next = &freepacks[i+1];
              }
       }
                                   /* set up signal handling */
       sigdie(SIGINT, "Interrupt");
       sigdie(SIGTERM, "Terminate");
#ifdef SIGHUP
       sigdie(SIGHUP, "Hangup");
#endif
#ifdef SIGPIPE
       sigdie(SIGPIPE, "Broken pipe");
#endif
#ifdef SIGALRM
       sigdie(SIGALRM, "Alarm clock");
#endif
#ifdef SIGXCPU
       sigdie(SIGXCPU, "CPU limit exceeded");
#endif
#ifdef SIGXFSZ
       sigdie(SIGXFSZ, "File size exceeded");
#endif
                                   /* protect holodeck file */
       orig_mode = resfmode(hdlist[0]->fd, (ncprocs>0) & (force>=0) ? 0 : 0444);
       return;
memerr:
       error(SYSTEM, "out of memory in initrholo");
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void loadholo ( void  ) [static]

Definition at line 520 of file rholo.c.

{
       FILE   *fp;
       int    fd;
       int    n;
       int32  nextloc;
       
       if ((ncprocs > 0) & (force >= 0))
              fp = fopen(hdkfile, "r+");
       else
              fp = NULL;
       if (fp == NULL) {
              if ((fp = fopen(hdkfile, "r")) == NULL) {
                     sprintf(errmsg, "cannot open \"%s\"", hdkfile);
                     error(SYSTEM, errmsg);
              }
              if (ncprocs > 0) {
                     sprintf(errmsg, "\"%s\" is read-only", hdkfile);
                     if (outdev == NULL)
                            error(USER, errmsg);
                     strcat(errmsg, "; new rays will be discarded");
                     error(WARNING, errmsg);
                     force = -1;
              }
       }
                                   /* load variables from header */
       getheader(fp, headline, NULL);
                                   /* check magic number */
       if (getw(fp) != HOLOMAGIC) {
              sprintf(errmsg, "bad magic number in holodeck file \"%s\"",
                            hdkfile);
              error(USER, errmsg);
       }
       nextloc = ftell(fp);               /* get stdio position */
       fd = dup(fileno(fp));
       fclose(fp);                        /* done with stdio */
       for (n = 0; nextloc > 0L; n++) {   /* initialize each section */
              lseek(fd, (off_t)nextloc, SEEK_SET);
              read(fd, (char *)&nextloc, sizeof(nextloc));
              hdinit(fd, NULL);
       }
       if (n != vdef(SECTION)) {
              sprintf(errmsg, "number of sections does not match %s setting",
                            vnam(SECTION));
              error(WARNING, errmsg);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char *  argv[] 
)

Definition at line 86 of file rholo.c.

{
       int    i;

       progname = argv[0];                /* get arguments */
       for (i = 1; i < argc && argv[i][0] == '-'; i++)
              switch (argv[i][1]) {
              case 'w':                   /* turn off warnings */
                     nowarn++;
                     break;
              case 'f':                   /* force overwrite */
                     force = 1;
                     break;
              case 'r':                   /* read-only mode */
                     force = -1;
                     break;
              case 'i':                   /* read input from stdin */
                     readinp++;
                     break;
              case 'n':                   /* compute processes */
                     if (i >= argc-2)
                            goto userr;
                     ncprocs = atoi(argv[++i]);
                     break;
              case 'o':                   /* output display */
                     if (i >= argc-2)
                            goto userr;
                     outdev = argv[++i];
                     break;
              default:
                     goto userr;
              }
                                          /* get root file name */
       if (i >= argc)
              goto userr;
       rootname(froot, hdkfile=argv[i++]);
                                          /* load variables? */
       if (i < argc)
              if (argv[i][0] != '-' && argv[i][0] != '+')
                     loadvars(argv[i]);   /* load variables from file */

       if (i >= argc || argv[i][0] == '+')
              loadholo();                 /* load existing holodeck */

       while (++i < argc)                 /* get command line settings */
              if (setvariable(argv[i], matchvar) < 0) {
                     sprintf(errmsg, "unknown variable: %s", argv[i]);
                     error(USER, errmsg);
              }
                                          /* check settings */
       checkvalues();
                                          /* load rad input file */
       getradfile();

       if (hdlist[0] == NULL) {           /* create new holodeck */
              HDGRID hdg[HDMAX];
                                                 /* set defaults */
              setdefaults(hdg);
                                                 /* check read-only */
              if (force < 0)
                     error(USER, "cannot create read-only holodeck");
                                                 /* holodeck exists? */
              if (!force && access(hdkfile, R_OK|W_OK) == 0)
                     error(USER,
                            "holodeck file exists -- use -f to overwrite");
                                                 /* create holodeck */
              creatholo(hdg);
       } else                             /* else just set defaults */
              setdefaults(NULL);
                                          /* initialize */
       initrholo();
                                          /* main loop */
       while (rholo())
              ;
                                          /* done */
       quit(0);
userr:
       fprintf(stderr,
"Usage: %s [-n nprocs][-o disp][-i][-w][-r|-f] output.hdk [control.hif|+|- [VAR=val ..]]\n",
                     progname);
       quit(1);
       return 1; /* pro forma return */
}

Here is the call graph for this function:

static void onsig ( int  signo) [static]

Definition at line 175 of file rholo.c.

{
       static int  gotsig = 0;

       if (gotsig > 1)                    /* we're going as fast as we can! */
              return;
       if (gotsig++) {                    /* two signals and we split */
              hdsync(NULL, 0);     /* don't leave w/o saying goodbye */
              _exit(signo);
       }
       alarm(300);                 /* allow 5 minutes to clean up */
       eputs("signal - ");
       eputs(sigerr[signo]);
       eputs("\n");
       quit(3);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void quit ( int  ec)

Definition at line 654 of file rholo.c.

{
       int    status = 0;

       if (hdlist[0] != NULL) {    /* close holodeck */
              if (nprocs > 0)
                     status = done_rtrace();            /* calls hdsync() */
              if ((ncprocs > 0) & (force >= 0) && vdef(REPORT)) {
                     off_t  fsiz, fuse;
                     fsiz = hdfilen(hdlist[0]->fd);
                     fuse = hdfiluse(hdlist[0]->fd);
                     fprintf(stderr,
                     "%s: %.1f Mbyte holodeck file, %.1f%% fragmentation\n",
                                   hdkfile, fsiz/(1024.*1024.),
                                   100.*(fsiz-fuse)/fsiz);
              }
       }
       if (orig_mode >= 0)         /* reset holodeck access mode */
              fchmod(hdlist[0]->fd, orig_mode);
       if (outdev != NULL)         /* close display */
              disp_close();
       exit(ec ? ec : status);            /* exit */
}

Here is the call graph for this function:

static int resfmode ( int  fd,
int  mod 
) [static]

Definition at line 208 of file rholo.c.

{
       struct stat   stbuf;
                                   /* get original mode */
       if (fstat(fd, &stbuf) < 0)
              error(SYSTEM, "cannot stat open holodeck file");
       mod &= stbuf.st_mode;              /* always more restrictive */
       if (mod == (stbuf.st_mode & 0777))
              return(-1);          /* already set */
                                   /* else change it */
       if (fchmod(fd, mod) < 0) {
              error(WARNING, "cannot change holodeck file access mode");
              return(-1);
       }
       return(stbuf.st_mode);             /* return original mode */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int rholo ( void  ) [static]

Definition at line 320 of file rholo.c.

{
       static off_t  nextfragwarn = 100L<<20;
       static int    idle = 0;
       PACKET *pl = NULL, *plend;
       off_t  fsiz;
       int    pksiz;
       register PACKET      *p;
       time_t t;
                                   /* check display */
       if (nprocs <= 0)
              idle = 1;
       if (outdev != NULL) {
              if (!disp_check(idle))
                     return(0);    /* quit request */
              if (nprocs <= 0)
                     return(1);
       } else if (idle)
              return(0);           /* all done */
       fsiz = hdfilen(hdlist[0]->fd);     /* check file size */
       if (maxdisk > 0 && fsiz >= maxdisk) {
              error(USER, "file limit exceeded");
              done_rtrace();
              return(1);    /* comes back */
       }
#if FRAGWARN
       if (fsiz >= nextfragwarn) {
              double pctfrag = 100.*(fsiz-hdfiluse(hdlist[0]->fd))/fsiz;
                     if (pctfrag >= (double)FRAGWARN) {
                     sprintf(errmsg, "holodeck file fragmentation is %.0f%%",
                                   pctfrag);
                     error(WARNING, errmsg);
                     nextfragwarn = fsiz + (fsiz>>2);
              } else
                     nextfragwarn = fsiz + (10L<<20);
       }
#endif
       t = time(NULL);                    /* check time */
       if (endtime > 0 && t >= endtime) {
              error(USER, "time limit exceeded");
              done_rtrace();
              return(1);    /* comes back */
       }
       if (reporttime > 0 && t >= reporttime)
              report(t);
                                   /* figure out good packet size */
       pksiz = RPACKSIZ;
#if MAXQTIME
       if (!chunkycmp) {
              pksiz = nraysdone*MAXQTIME/(totqlen*(t - starttime + 1L));
              if (pksiz < 1) pksiz = 1;
              else if (pksiz > RPACKSIZ) pksiz = RPACKSIZ;
       }
#endif
       idle = 0;                   /* get packets to process */
       while (freepacks != NULL) {
              p = freepacks; freepacks = p->next; p->next = NULL;
              if (!next_packet(p, pksiz)) {
                     p->next = freepacks; freepacks = p;
                     idle = 1;
                     break;
              }
              if (pl == NULL) pl = p;
              else plend->next = p;
              plend = p;
       }
                                   /* process packets */
       done_packets(do_packets(pl));
       return(1);                  /* and continue */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void rootname ( char *  rn,
char *  fn 
) [static]

Here is the caller graph for this function:

static void rootname ( register char *  rn,
register char *  fn 
) [static]

Definition at line 605 of file rholo.c.

{
       char   *tp, *dp;

       for (tp = NULL, dp = rn; (*rn = *fn++); rn++) {
              if (*rn == '/')
                     dp = rn;
              else if (*rn == '.')
                     tp = rn;
       }
       if (tp != NULL && tp > dp)
              *tp = '\0';
}
static void setdefaults ( HDGRID gp) [static]

Here is the caller graph for this function:

static void setdefaults ( register HDGRID gp) [static]

Definition at line 393 of file rholo.c.

{
       extern char   *atos();
       register int  i;
       int    n;
       double len[3], d;

       if (!vdef(SECTION)) {
              sprintf(errmsg, "%s must be defined", vnam(SECTION));
              error(USER, errmsg);
       }
       if (!vdef(OCTREE)) {
              if ((vval(OCTREE) = bmalloc(strlen(froot)+5)) == NULL)
                     error(SYSTEM, "out of memory");
              sprintf(vval(OCTREE), "%s.oct", froot);
              vdef(OCTREE)++;
       }
       if (!vdef(VDIST)) {
              vval(VDIST) = "F";
              vdef(VDIST)++;
       }
                            /* append rendering options */
       if (vdef(RENDER))
              rtargc += wordstring(rtargv+rtargc, vval(RENDER));
       
       if (gp == NULL)             /* already initialized? */
              return;
                            /* set grid parameters */
       for (n = 0; n < vdef(SECTION); n++, gp++) {
              gp->grid[0] = gp->grid[1] = gp->grid[2] = 0;
              if (sscanf(nvalue(SECTION, n),
              "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %hd %hd %hd",
                            &gp->orig[0], &gp->orig[1], &gp->orig[2],
                            &gp->xv[0][0], &gp->xv[0][1], &gp->xv[0][2],
                            &gp->xv[1][0], &gp->xv[1][1], &gp->xv[1][2],
                            &gp->xv[2][0], &gp->xv[2][1], &gp->xv[2][2],
                            &gp->grid[0], &gp->grid[1], &gp->grid[2]) < 12)
                     badvalue(SECTION);
              for (i = 0; i < 3; i++)
                     len[i] = VLEN(gp->xv[i]);
              if (!vdef(GRID)) {
                     d = 2/2e5*( len[0]*len[0]*(len[1]*len[1] +
                                   len[2]*len[2] + 4*len[1]*len[2])
                            + len[1]*len[1]*len[2]*(len[2] + 4*len[0])
                            + 4*len[0]*len[1]*len[2]*len[2] );
                     d = sqrt(sqrt(d));
              } else if ((d = vflt(GRID)) <= FTINY)
                     badvalue(GRID);
              for (i = 0; i < 3; i++)
                     if (gp->grid[i] <= 0)
                            gp->grid[i] = len[i]/d + (1.-FTINY);
       }
}

Here is the call graph for this function:

static void sigdie ( int  signo,
char *  msg 
) [static]

Definition at line 196 of file rholo.c.

{
       if (signal(signo, onsig) == SIG_IGN)
              signal(signo, SIG_IGN);
       sigerr[signo] = msg;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

time_t endtime

Definition at line 52 of file rholo.c.

int force = 0

Definition at line 49 of file rholo.c.

Definition at line 65 of file rholo.c.

char froot[256]

Definition at line 41 of file rholo.c.

char* hdkfile

Definition at line 40 of file rholo.c.

gethfunc headline [static]

Definition at line 79 of file rholo.c.

off_t maxdisk

Definition at line 55 of file rholo.c.

int ncprocs = 0

Definition at line 43 of file rholo.c.

int nowarn

Definition at line 92 of file rcalc.c.

long npacksdone = 0L

Definition at line 63 of file rholo.c.

long nraysdone = 0L

Definition at line 62 of file rholo.c.

int NVARS = NRHVARS

Definition at line 35 of file rholo.c.

int orig_mode = -1

Definition at line 60 of file rholo.c.

char* outdev = NULL

Definition at line 45 of file rholo.c.

char* progname

Definition at line 39 of file rholo.c.

const char RCSid[] = "$Id: rholo.c,v 3.74 2008/12/05 00:22:33 greg Exp $" [static]

Definition at line 2 of file rholo.c.

int readinp = 0

Definition at line 47 of file rholo.c.

time_t reporttime

Definition at line 53 of file rholo.c.

int rtargc = 1

Definition at line 57 of file rholo.c.

char* rtargv[128] = {"rtrace", NULL}

Definition at line 58 of file rholo.c.

char* sigerr[NSIG]

Definition at line 68 of file rholo.c.

time_t starttime

Definition at line 51 of file rholo.c.

int totqlen

Definition at line 66 of file rholo.c.

Definition at line 37 of file rholo.c.