home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / inetray / inetray.c < prev    next >
C/C++ Source or Header  |  1992-06-30  |  13KB  |  488 lines

  1. /*======================================================================
  2.                     I N E T R A Y . C 
  3.                     doc: Mon Feb 24 16:20:04 1992
  4.                     dlm: Wed Jul  1 12:48:09 1992
  5.                     (c) 1992 ant@julia
  6.                     uE-Info: 178 56 T 0 0 72 2 2 8 ofnI
  7. ======================================================================*/
  8.  
  9. /*#define        PRINTSCHEDULE        /* print scheduling info */
  10.  
  11. #include    <stdio.h>        /* here we go! */
  12. #include    <signal.h>
  13. #include    <errno.h>
  14. #include    <fcntl.h>
  15. #include    <string.h>
  16. #include    <sys/types.h>
  17. #include    <sys/time.h>
  18. #include    <sys/param.h>
  19. #include    <sys/stat.h>
  20. #include    <rpc/rpc.h>
  21. #include    "inetray.h"
  22. #include    "common.h"
  23. #include    "comm.h"
  24. #include    "rayshade.h"
  25. #include    "options.h"
  26. #include    "picture.h"
  27. #include    "viewing.h"
  28. #include    "rcfile.h"
  29. #include    "config.h"
  30. #ifdef AUX_QUIRK
  31. #include    "aux_quirk.h"
  32. #endif
  33. #include    "version.h"
  34. #include    "patchlevel.h"
  35.  
  36. static Pixel    **line;            /* array for picture data */
  37. static int    bSize;            /* blocksize to trace in one sweep */
  38. static int    lSize;            /* size of last block in frame */
  39. static int    bNum;            /* number of blocks in frame */
  40. static char    *completed;        /* array for completed blocks */
  41. static int    doNext = 0;        /* next block to trace */
  42. static int    reDo = 0;        /* reDo # of outstanding blocks */
  43. static int    nCompleted = 0;        /* number of lines completed per frame */
  44. static int    bCompleted = 0;        /* number of blocks completed per frame */
  45. static int    nSvc;            /* number of registered servers */
  46. static int    nextB2W;        /* next block to write to pic file */
  47.  
  48. int    key;                /* session key (exported) */
  49.  
  50. extern    int errno;            /* error number to restart syscalls */
  51.  
  52. main(ac,av)
  53. int ac; char *av[];
  54. {
  55.     static void initSelf(),initSubDiv(),initFrame();
  56.     static void printStats(),distAll(),sigCaught(),writeBlocks();
  57.     static int  initServers();
  58.     int    fd;
  59.     char    buf[64];
  60.     
  61.     fprintf(stderr,"%s [%s%d]\n",av[0],VERSION,PATCHLEVEL);
  62.     initSelf(ac,av);            /* initialize self */
  63.  
  64.     key = (int)time(NULL);            /* session key */
  65.     fprintf(stderr,"Session Key = %d\n",key);
  66.     initServers(ac,av);            /* set up all servers */
  67.  
  68.     rename(KEYFILE,OLDKEYFILE);        /* save keyfile */
  69.     fd = open(KEYFILE,O_CREAT|O_WRONLY,0600);
  70.     if (fd < 0) {
  71.         perror("open");
  72.         exit(1);
  73.     }
  74.     sprintf(buf,"%ld\n",key);        /* in ASCII */
  75.     if (write(fd,buf,strlen(buf)) < 0) {
  76.         perror("write");
  77.         exit(1);
  78.     }
  79.     close(fd);
  80.  
  81.     initSubDiv();                /* init frame subdivision */
  82.  
  83.     for (Options.framenum=Options.startframe;
  84.          Options.framenum<=Options.endframe;
  85.           Options.framenum++) {
  86.         initFrame(Options.framenum);    /* init & send first requests */
  87.         PictureStart(av);        /* write picture in parallel */
  88.         distAll();            /* distribute remaining lines */
  89.         writeBlocks(TRUE);        /* write remaining blocks */
  90.         fprintf(stderr,"Cleaning up...");
  91.         killAll();            /* kill running workers */
  92.         flushAll();            /* discard pending input */
  93.         waitAll();            /* wait for workers to come down */
  94.         PictureFrameEnd();        /* end picture frame */
  95.     }
  96.     PictureEnd();
  97.     Options.framenum = Options.endframe;    /* fix for stats */
  98.     printStats();
  99.     fprintf(stderr,"Exiting..."); 
  100.     terminateAll();                /* now exit everything */
  101.     closeAll();
  102.     putc('\n',stderr);
  103.     exit(0);
  104. }
  105.  
  106. /*----------------------------------------------------------------------*/
  107. /*        initSelf and supporting routines            */
  108. /*----------------------------------------------------------------------*/
  109.  
  110. static void busError()                /* SUN4 weird bus errors */
  111. {
  112.     fprintf(stderr,"Warning: SIGBUS caught!\n");
  113. }
  114.  
  115. static void defSignals()            /* install default sigs */
  116. {
  117.     void    sigCaught();
  118.  
  119.     signal(SIGHUP,sigCaught);        /* all sigs which could mean */
  120.     signal(SIGINT,sigCaught);        /* terminate */
  121.     signal(SIGQUIT,sigCaught);
  122.     signal(SIGABRT,sigCaught);
  123.     signal(SIGTERM,sigCaught);
  124.     signal(SIGTSTP,sigCaught);
  125.     signal(SIGUSR1,sigCaught);
  126.     signal(SIGUSR2,sigCaught);
  127.     signal(SIGBUS,busError);        /* sometimes on SUN4s */
  128. }
  129.  
  130. static void sigCaught()                /* abort signal rcved */
  131. {
  132.     char     ans;
  133.     
  134.     fprintf(stderr,"\nSignal received...\nReally abort <y/n>?");
  135.     do 
  136.          ans = getchar();  
  137.     while ((ans != 'y') && (ans != 'Y') &&
  138.            (ans != 'n') && (ans != 'N'));
  139.     if ((ans == 'y') || (ans == 'Y')) shutDown();
  140.     defSignals();
  141. }
  142.     
  143.  
  144. static void initFrame(f)            /* init frame */
  145. int f;
  146. {
  147.     int     i;
  148.     void     dist1st();
  149.     
  150.     for (i=0; i<bNum; i++)             /* clear completed flags */
  151.         completed[i] = FALSE;
  152.     doNext = nCompleted = 0;        /* reset counters */
  153.     reDo = nextB2W = bCompleted = 0;
  154.     fprintf(stderr,"\nFrame #%d:\n",f); 
  155.     dist1st(f);                /* begin trace */
  156. }
  157.  
  158. static void initSelf(ac,av)            /* init stuff */
  159. int ac; char *av[];
  160. {
  161.     int     i,lnSize;
  162.     struct stat buf;
  163.  
  164. #ifdef S_ISSOCK
  165.     if (!isatty(IN) &&
  166.         (fstat(IN,&buf) >= 0) &&
  167.         (S_ISSOCK(buf.st_mode) || S_ISFIFO(buf.st_mode))) {
  168. #else
  169.     if (!isatty(IN)) {
  170. #endif
  171.         fprintf(stderr,"Error: Don't use in pipe!\n"); 
  172.         exit(1);
  173.     }
  174.  
  175.     readRc();                /* read .rc-file */
  176.     
  177.     RSInitialize(ac,av);            /* options, file, ... */
  178.     wait(NULL);                /* from popen() */
  179.     defSignals();                /* signals */
  180.  
  181.     line = (Pixel **)malloc(Screen.ysize * sizeof(Pixel *));
  182.     if (line == NULL) {
  183.         fprintf(stderr,"malloc() failed\n");
  184.         exit(1);
  185.     }
  186.     lnSize = Screen.xsize * sizeof(Pixel);
  187.     for (i=0; i<Screen.ysize; i++) {
  188.         line[i] = (Pixel *)malloc(lnSize);
  189.         if (line[i] == NULL) {
  190.             perror("malloc");
  191.             exit(1);
  192.         }
  193.     }
  194. }
  195.  
  196. static void initSubDiv()            /* init frame subdivision */
  197. {
  198.     bSize = Screen.ysize / nSvc
  199.             / blocksPerServer;    /* estimated size of blocks */
  200.     if (bSize < minBlockSize)        /* assert bounds */
  201.         bSize = minBlockSize;
  202.     if (bSize > maxBlockSize)
  203.         bSize = maxBlockSize;
  204.     bNum = Screen.ysize / bSize + 1;    /* number of blocks */
  205.     lSize = Screen.ysize-(bNum-1)*bSize;    /* remaining lines */
  206.     if (lSize == 0) {            /* no remaining lines */
  207.         bNum--;
  208.         lSize = bSize;
  209.     }
  210.  
  211.     completed = (char *)malloc(bNum);    /* supporting structures */
  212.     if (completed == NULL) {
  213.         fprintf(stderr,"malloc() failed\n");
  214.         exit(1);
  215.     }
  216.     fprintf(stderr,"Frame Subdivision:\n");
  217.     fprintf(stderr,"\t%d Blocks per Frame\n",bNum);
  218.     fprintf(stderr,"\t%d Lines per Block\n",bSize);
  219.     fprintf(stderr,"\t%d Lines in Last Block",lSize);
  220. }
  221.     
  222.  
  223. /*----------------------------------------------------------------------*/
  224. /*        distribution                         */
  225. /*----------------------------------------------------------------------*/
  226.  
  227. static int findNext()                /* next blockNr */
  228. {
  229.     int i,sm= -1,nx= -1;
  230.     static int next;
  231.  
  232.     for (i=0; i<bNum; i++)
  233.         if (!completed[i]) {
  234.             if (sm < 0) sm = i;
  235.             if ((nx < 0) && (i >= doNext)) nx = i;
  236.         }
  237.     if (sm < 0) return FALSE;
  238.     if (nx < 0) next = sm;            /* original next */
  239.     else next = nx;
  240.     
  241.     if (reDo > 0) {                /* rescheduled */
  242.         reDo--;
  243.         doNext = sm;
  244.     } else {
  245.         doNext = next;
  246.     }
  247.     return TRUE;
  248. }
  249.  
  250. static void dist1st(frame)            /* dist 1 block p. server */
  251. int frame;
  252. {
  253.     hInfo    *host;
  254.     int     *res;
  255.     sfPrm    paramSF;
  256.     tbPrm    paramTB;
  257.     
  258.     for (host = hosts; host != NULL; host = host->next) {
  259.         if (doNext == bNum) return;    /* more servers than blocks */
  260.         host->fDone = 0;
  261.         if (host->broken) continue;
  262.         paramSF.key = key;
  263.         paramSF.fNr = frame;
  264.         res = startframe_1(¶mSF,host->clnt);
  265.         if (res == (int *)NULL) {
  266.             fprintf(stderr,"startframe(): ");
  267.             abort1(host);
  268.         }
  269.         paramTB.key = key;
  270.         paramTB.bNr = doNext;
  271.         paramTB.bSz = (doNext == bNum-1) ? lSize : bSize;
  272.         paramTB.lNr = doNext*bSize;
  273.         clnt_call(host->clnt,TRACEBLOCK,
  274.                 xdr_tbPrm,¶mTB,
  275.                 xdr_void,NULL,now);
  276. #ifdef PRINTSCHEDULE
  277.         fprintf(stderr,"\tBlock #%d sent to %s\n",doNext,host->name);
  278. #endif
  279.         doNext++;
  280.     }
  281. }
  282.         
  283. static void printStats()            /* print statistics */
  284. {
  285.     hInfo    *host,*bHost;
  286.     int    tot,all,best;
  287.     char    nBuf[MAXHOSTNAMELEN+10];
  288.  
  289.     signal(SIGINT,sigCaught); 
  290.     fprintf(stderr,"\nStatistics:\n"); 
  291.     tot = (Options.framenum-Options.startframe)*Screen.ysize+nCompleted;
  292.     if (tot == 0) tot = 1;
  293.     for (all=0; all<nSvc; all++) {
  294.         best = 0;
  295.         for (host = hosts; host != NULL; host = host->next) 
  296.                 if (host->done >= best) {
  297.                     best = host->done;
  298.                     bHost = host;
  299.                 }
  300.         if (bHost->done == 0) bHost->done = -1;
  301.         else bHost->done = -bHost->done;
  302.         putc('\t',stderr);
  303.         sprintf(nBuf,"%s[%d]",bHost->name,bHost->pid);
  304.         fprintf(stderr,"\t%-15.14s",nBuf);
  305.         if (bHost->broken) fprintf(stderr,"# ");
  306.         else fprintf(stderr,"  ");
  307.         fprintf(stderr,"%d \t(%d%%)\n",best,100*best/tot);
  308.     }
  309.     for (host = hosts; host != NULL; host = host->next)
  310.         if (host->done == -1) host->done = 0;
  311.         else host->done = -host->done;
  312. }
  313.  
  314. static void writeBlocks(flush)
  315. char flush;
  316. {
  317.     int     i,bSz,writ = 0;            /* write to file */
  318.     hInfo     *h;
  319.     fd_set    sockSet;
  320.     
  321.     while ((nextB2W < bNum) && completed[nextB2W]) {
  322.         if (writ == 0)
  323.             fprintf(stderr,"\tWriting... ");
  324.         bSz = (nextB2W == bNum-1) ? lSize : bSize;
  325.         for (i=0; i<bSz; i++)
  326.             PictureWriteLine(line[nextB2W*bSize+i]);
  327.         nextB2W++; writ++;
  328.         if (!flush) {            /* check for input */
  329.                 FD_ZERO(&sockSet);
  330.             for (h = hosts; h != NULL; h = h->next)
  331.                 if (!h->broken)
  332.                     FD_SET(h->sock,&sockSet);
  333.                 if (select(sfdmax+1,&sockSet,
  334.                     (fd_set *)NULL,(fd_set *)NULL,
  335.                     &now) != 0) {
  336.                 fprintf(stderr,"[interrupted] ");
  337.                 break;
  338.             }
  339.         }
  340.     }
  341.     if (writ == 1)                /* report it */
  342.         fprintf(stderr,"(1 block)\n");
  343.     else if (writ > 1)
  344.         fprintf(stderr,"(%d blocks)\n",writ);
  345. }
  346.  
  347. static char getBlock(host)            /* get traced block */
  348. hInfo *host;
  349. {
  350.     pixArr    xdrline;
  351.     int    bNr,bSz,i;            /* block info */
  352.     XDR     *xdrs;
  353.     hInfo    *h;
  354.     
  355.     xdrs = &(host->xdrs);
  356.       if (!xdrrec_skiprecord(xdrs)) {     /* read next record*/
  357.           fprintf(stderr,"xdrrec_skiprecord(): ");
  358.           abort1(host);
  359.         return FALSE;
  360.     }
  361.     if (!xdr_int(xdrs,&bNr)) {        /* get block number */
  362.         abort1(host);
  363.         return FALSE;
  364.     }
  365.  
  366.     bSz = (bNr == bNum-1) ? lSize : bSize;    /* calc block size */
  367.  
  368.     for (i=0; i<bSz; i++) {            /* read all lines */
  369.             xdrline.pixArr_val = (xdrPix *)line[bNr*bSize+i];
  370.             if (!xdr_pixArr(xdrs,&xdrline)) {
  371.                     fprintf(stderr,"xdr_pixArr(): ");
  372.             abort1(host);
  373.             return FALSE;
  374.         }
  375.     }
  376. #ifdef PRINTSCHEDULE
  377.     fprintf(stderr,"\tBlock #%d received from %s\n",bNr,host->name);
  378. #endif
  379.     if (!completed[bNr]) {            /* reporting & statistics */
  380.         completed[bNr] = TRUE;
  381.         if (nCompleted/Options.report_freq <
  382.             (nCompleted+bSz)/Options.report_freq) {
  383.             fprintf(stderr,"\tFinished line %d\n",nCompleted+bSz);
  384.         }
  385.         nCompleted += bSz;        /* update stats */
  386.         bCompleted++;
  387.         host->done += bSz;
  388.         host->fDone += bSz;
  389.         if (bCompleted == bNum/2) {
  390.             for (h = hosts; h != NULL; h = h->next)
  391.                 if (h->fDone == 0) reDo++;
  392.             if (reDo > bNum/4) reDo = 0;
  393.             if (reDo == 1)
  394.                 fprintf(stderr,"\t1 block rescheduled\n");
  395.             else
  396.                 fprintf(stderr,"\t%d blocks rescheduled\n",reDo);
  397.         }
  398.     }
  399.     writeBlocks(FALSE);    
  400.     return TRUE;
  401. }
  402.  
  403.     
  404. static void distAll()                /* block distribution routine */
  405. {
  406.     fd_set    sockSet;
  407.     int        res;
  408.     hInfo    *host;
  409.     tbPrm    param;
  410.  
  411.     do {                    /* loop on all blocks */
  412.     signal(SIGINT,printStats);
  413.     restartSelect:
  414.         FD_ZERO(&sockSet);            /* select() on sockets */
  415.     for (host = hosts; host != NULL; host = host->next)
  416.         if (!host->broken)
  417.             FD_SET(host->sock,&sockSet);
  418.         res = select(sfdmax+1,&sockSet,(fd_set *)NULL,(fd_set *)NULL,
  419.             (struct timeval *)NULL); 
  420.         if (res < 0) {
  421.             if (errno == EINTR) goto restartSelect;
  422.                 perror("select");
  423.         exit(1);
  424.     }
  425.     for (host = hosts; host != NULL; host = host->next) {
  426.             if (!FD_ISSET(host->sock,&sockSet)) continue;
  427.             if (host->broken) continue;
  428.             if (!getBlock(host))        /* read one result */
  429.             continue;        /* connection broken */
  430.         if (!findNext()) return;    /* next line to trace */
  431.         param.key = key;        /* next block */
  432.         param.bNr = doNext;
  433.         param.bSz = (doNext == bNum-1) ? lSize : bSize;
  434.         param.lNr = doNext * bSize;
  435.         clnt_call(host->clnt,TRACEBLOCK,
  436.                 xdr_tbPrm,¶m,
  437.                 xdr_void,NULL,
  438.                 now);
  439. #ifdef PRINTSCHEDULE
  440.         fprintf(stderr,"\tBlock #%d sent to %s\n",doNext,host->name);
  441. #endif
  442.         doNext++;
  443.     } 
  444.     } FOREVER;                    
  445. }
  446.  
  447. /*----------------------------------------------------------------------*/
  448. /*        initClients()                        */
  449. /*----------------------------------------------------------------------*/
  450.  
  451. static char *makePStr(ac,av)            /* build param-str */
  452. int ac; char *av[];
  453. {
  454.     int abp,ap,i;
  455.     static char argbuf[256];
  456.  
  457.     for (abp=0,ap=0; ap < ac; ap++) {
  458.         argbuf[abp++] = '\'';
  459.         for (i=0; av[ap][i] != '\0'; i++)
  460.             argbuf[abp++] = av[ap][i];
  461.         argbuf[abp++] = '\'';
  462.         argbuf[abp++] = ' ';
  463.     }
  464.     argbuf[abp] = '\0';
  465.     return argbuf;
  466. }
  467.  
  468. static int initServers(ac,av)            /* init all servers */
  469. int ac; char *av[];
  470. {
  471.     char    cwd[MAXPATHLEN],hname[MAXHOSTNAMELEN];
  472.     char    *getwd();
  473.  
  474.     if (gethostname(hname,MAXHOSTNAMELEN) < 0) {
  475.         perror("gethostname");
  476.         exit(1);
  477.     }
  478.     fprintf(stderr,"Registering... ["); 
  479.     registerSvc(hname,makePStr(ac,av),getwd(cwd));
  480.     nSvc = nRunning;
  481.     if (nSvc == 0) {
  482.         fprintf(stderr,"\nError: no Inetray Servers answering!\n");
  483.         exit(1);
  484.     }
  485.     fprintf(stderr,"\n[%d workers registered]\n",nSvc); 
  486. }
  487.  
  488.