home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume11 / musbus / part02 / dummy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-09-16  |  6.6 KB  |  303 lines

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