home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / byteunix.lzh / byte.2 / dummy.c next >
C/C++ Source or Header  |  1990-05-11  |  7KB  |  319 lines

  1.  
  2. /*******************************************************************************
  3.  *  The BYTE UNIX Benchmarks - Release 2
  4.  *          Module: dummy.c   SID: 2.4 4/17/90 16:45:32
  5.  *          
  6.  *******************************************************************************
  7.  * Bug reports, patches, comments, suggestions should be sent to:
  8.  *
  9.  *    Ben Smith or Rick Grehan at BYTE Magazine
  10.  *    bensmith@bixpb.UUCP    rick_g@bixpb.UUCP
  11.  *
  12.  *******************************************************************************
  13.  *  Modification Log:
  14.  *
  15.  ******************************************************************************/
  16. char SCCSid[] = "@(#) @(#)dummy.c:2.4 -- 4/17/90 16:45:32";
  17. /*
  18.  *  Hacked up C program for use in the standard shell.? scripts of
  19.  *  the multiuser test.  This is based upon makework.c, and is typically
  20.  *  edited using edscript.2 before compilation.
  21.  *
  22.  * $Header: dummy.c,v 3.4 87/06/23 15:54:53 kjmcdonell Beta $
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <signal.h>
  27.  
  28. #define DEF_RATE    5.0
  29. #define GRANULE        5
  30. #define CHUNK        60
  31. #define MAXCHILD    12
  32. #define MAXWORK        10
  33.  
  34. float    thres;
  35. float    est_rate = DEF_RATE;
  36. int    nusers;        /* number of concurrent users to be simulated by
  37.              * this process */
  38. int    firstuser;    /* ordinal identification of first user for this
  39.              * process */
  40. int    nwork = 0;    /* number of job streams */
  41. int    exit_status = 0;    /* returned to parent */
  42. int    sigpipe;    /* pipe write error flag */
  43.  
  44. struct st_work {
  45.     char    *cmd;        /* name of command to run */
  46.     char    **av;        /* arguments to command */
  47.     char    *input;        /* standard input buffer */
  48.     int    inpsize;    /* size of standard input buffer */
  49. } work[MAXWORK];
  50.  
  51. struct {
  52.     int    xmit;    /* # characters sent */
  53.     char    *bp;    /* std input buffer pointer */
  54.     int    blen;    /* std input buffer length */
  55.     int    fd;    /* stdin to command */
  56.     int    pid;    /* child PID */
  57.     char    *line;    /* start of input line */ 
  58.     int    firstjob;    /* inital piece of work */
  59.     int    thisjob;    /* current piece of work */
  60. } child[MAXCHILD], *cp;
  61.  
  62. main(argc, argv)
  63. int    argc;
  64. char    *argv[];
  65. {
  66.     int        i;
  67.     int        l;
  68.     int        fcopy = 0;    /* fd for copy output */
  69.     int        master = 1;    /* the REAL master, == 0 for clones */
  70.     int        nchild;        /* no. of children for a clone to run */
  71.     int        done;        /* count of children finished */
  72.     int        output;        /* aggregate output char count for all
  73.                    children */
  74.     int        c;
  75.     int        thiswork = 0;    /* next job stream to allocate */
  76.     int        nch;        /* # characters to write */
  77.     int        written;    /* # characters actully written */
  78.     char    logname[15];    /* name of the log file(s) */
  79.     int        onalarm();
  80.     int        pipeerr();
  81.     int        wrapup();
  82.     int        grunt();
  83.     char    *malloc();
  84.     int        pvec[2];    /* for pipes */
  85.     char    *p;
  86.     char    *prog;        /* my name */
  87.  
  88. #if ! debug
  89.     freopen("masterlog.00", "a", stderr);
  90. #endif
  91.     fprintf(stderr, "*** New Run ***  ");
  92.     prog = argv[0];
  93.     while (argc > 1 && argv[1][0] == '-')  {
  94.     p = &argv[1][1];
  95.     argc--;
  96.     argv++;
  97.     while (*p) {
  98.         switch (*p) {
  99.         case 'r':
  100.             /* code DELETED here */
  101.             argc--;
  102.             argv++;
  103.             break;
  104.  
  105.         case 'c':
  106.             /* code DELETED here */
  107.             lseek(fcopy, 0L, 2);    /* append at end of file */
  108.             break;
  109.  
  110.         default:
  111.         fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
  112.             exit(4);
  113.         }
  114.         p++;
  115.     }
  116.     }
  117.     
  118.     if (argc < 2) {
  119.     fprintf(stderr, "%s: missing nusers\n", prog);
  120.     exit(4);
  121.     }
  122.  
  123.     nusers = atoi(argv[1]);
  124.     if (nusers < 1) {
  125.     fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
  126.     exit(4);
  127.     }
  128.     fprintf(stderr, "%d Users\n", nusers);
  129.     argc--;
  130.     argv++;
  131.  
  132.     /* build job streams */
  133.     getwork();
  134. #if debug
  135.     dumpwork();
  136. #endif
  137.  
  138.     /* clone copies of myself to run up to MAXCHILD jobs each */
  139.     firstuser = MAXCHILD;
  140.     fprintf(stderr, "master pid %d\n", getpid());
  141.     fflush(stderr);
  142.     while (nusers > MAXCHILD) {
  143.     fflush(stderr);
  144.     if (nusers >= 2*MAXCHILD)
  145.         /* the next clone must run MAXCHILD jobs */
  146.         nchild = MAXCHILD;
  147.     else
  148.         /* the next clone must run the leftover jobs */
  149.         nchild = nusers - MAXCHILD;
  150.     if ((l = fork()) == -1) {
  151.         /* fork failed */
  152.         fatal("** clone fork failed **\n");
  153.         goto bepatient;
  154.     } else if (l > 0) {
  155.         fprintf(stderr, "master clone pid %d\n", l);
  156.         /* I am the master with nchild fewer jobs to run */
  157.         nusers -= nchild;
  158.         firstuser += MAXCHILD;
  159.         continue;
  160.     } else {
  161.         /* I am a clone, run MAXCHILD jobs */
  162. #if ! debug
  163.         sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
  164.         freopen(logname, "w", stderr);
  165. #endif
  166.         master = 0;
  167.         nusers = nchild;
  168.         break;
  169.     }
  170.     }
  171.     if (master)
  172.     firstuser = 0;
  173.  
  174.     close(0);
  175.  
  176.     /* code DELETED here */
  177.  
  178.     fflush(stderr);
  179.  
  180.     srand(time(0));
  181.     thres = 0;
  182.     done = output = 0;
  183.     for (i = 0; i < nusers; i++) {
  184.     if (child[i].blen == 0)
  185.         done++;
  186.     else
  187.         thres += est_rate * GRANULE;
  188.     }
  189.     est_rate = thres;
  190.  
  191.     signal(SIGALRM, onalarm);
  192.     signal(SIGPIPE, pipeerr);
  193.     alarm(GRANULE);
  194.     while (done < nusers) {
  195.     for (i = 0; i < nusers; i++) {
  196.         cp = &child[i];
  197.         if (cp->xmit >= cp->blen) continue;
  198.         l = rand() % CHUNK + 1;    /* 1-CHUNK chars */
  199.         if (l == 0) continue;
  200.         if (cp->xmit + l > cp->blen)
  201.         l = cp->blen - cp->xmit;
  202.         p = cp->bp;
  203.         cp->bp += l;
  204.         cp->xmit += l;
  205. #if debug
  206.         fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
  207. #endif
  208.         while (p < cp->bp) {
  209.         if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
  210.             /* write it out */
  211.             nch = p - cp->line + 1;
  212.             if ((written = write(cp->fd, cp->line, nch)) != nch) {
  213.  
  214.             /* code DELETED here */
  215.  
  216.             }
  217.             if (fcopy)
  218.             write(fcopy, cp->line, p - cp->line + 1);
  219. #if debug
  220.             fprintf(stderr, "child %d gets \"", i);
  221.             {
  222.             char *q = cp->line;
  223.             while (q <= p) {
  224.                 if (*q >= ' ' && *q <= '~')
  225.                     fputc(*q, stderr);
  226.                 else
  227.                     fprintf(stderr, "\\%03o", *q);
  228.                 q++;
  229.             }
  230.             }
  231.             fputc('"', stderr);
  232. #endif
  233.             cp->line = &p[1];
  234.         }
  235.         p++;
  236.         }
  237.         if (cp->xmit >= cp->blen) {
  238.         done++;
  239.         close(cp->fd);
  240. #if debug
  241.     fprintf(stderr, "child %d, close std input\n", i);
  242. #endif
  243.         }
  244.         output += l;
  245.     }
  246.     while (output > thres) {
  247.         pause();
  248. #if debug
  249.         fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
  250. #endif
  251.     }
  252.     }
  253.  
  254. bepatient:
  255.     alarm(0);
  256. /****
  257.  *  If everything is going OK, we should simply be able to keep
  258.  *  looping unitil 'wait' fails, however some descendent process may
  259.  *  be in a state from which it can never exit, and so a timeout
  260.  *  is used.
  261.  *  5 minutes should be ample, since the time to run all jobs is of
  262.  *  the order of 5-10 minutes, however some machines are painfully slow,
  263.  *  so the timeout has been set at 20 minutes (1200 seconds).
  264.  ****/
  265.  
  266.     /* code DELETED here */
  267.  
  268. }
  269.  
  270. onalarm()
  271. {
  272.     thres += est_rate;
  273.     signal(SIGALRM, onalarm);
  274.     alarm(GRANULE);
  275. }
  276.  
  277. grunt()
  278. {
  279.     /* timeout after label "bepatient" in main */
  280.     exit_status = 4;
  281.     wrapup();
  282. }
  283.  
  284. pipeerr()
  285. {
  286.     sigpipe++;
  287. }
  288.  
  289. wrapup()
  290. {
  291.     /* DUMMY, real code dropped */
  292. }
  293.  
  294. getwork()
  295. {
  296.  
  297.     /* DUMMY, real code dropped */
  298.     gets();
  299.     strncpy();
  300.     malloc(); realloc();
  301.     open(); close();
  302. }
  303.  
  304. fatal(s)
  305. char *s;
  306. {
  307.     int    i;
  308.     fprintf(stderr, s);
  309.     fflush(stderr);
  310.     perror("Reason?");
  311.     for (i = 0; i < nusers; i++) {
  312.     if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1)
  313.         fprintf(stderr, "pid %d killed off\n", child[i].pid);
  314.     }
  315.     fflush(stderr);
  316.     exit_status = 4;
  317.     return;
  318. }
  319.