home *** CD-ROM | disk | FTP | other *** search
- /*
- * Hacked up C program for use in the standard shell.? scripts of
- * the multiuser test. This is based upon makework.c, and is typically
- * edited using edscript.2 before compilation.
- *
- * $Header: dummy.c,v 3.4 87/06/23 15:54:53 kjmcdonell Beta $
- */
-
- #include <stdio.h>
- #include <signal.h>
-
- #define DEF_RATE 5.0
- #define GRANULE 5
- #define CHUNK 60
- #define MAXCHILD 12
- #define MAXWORK 10
-
- float thres;
- float est_rate = DEF_RATE;
- int nusers; /* number of concurrent users to be simulated by
- * this process */
- int firstuser; /* ordinal identification of first user for this
- * process */
- int nwork = 0; /* number of job streams */
- int exit_status = 0; /* returned to parent */
- int sigpipe; /* pipe write error flag */
-
- struct st_work {
- char *cmd; /* name of command to run */
- char **av; /* arguments to command */
- char *input; /* standard input buffer */
- int inpsize; /* size of standard input buffer */
- } work[MAXWORK];
-
- struct {
- int xmit; /* # characters sent */
- char *bp; /* std input buffer pointer */
- int blen; /* std input buffer length */
- int fd; /* stdin to command */
- int pid; /* child PID */
- char *line; /* start of input line */
- int firstjob; /* inital piece of work */
- int thisjob; /* current piece of work */
- } child[MAXCHILD], *cp;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int i;
- int l;
- int fcopy = 0; /* fd for copy output */
- int master = 1; /* the REAL master, == 0 for clones */
- int nchild; /* no. of children for a clone to run */
- int done; /* count of children finished */
- int output; /* aggregate output char count for all
- children */
- int c;
- int thiswork = 0; /* next job stream to allocate */
- int nch; /* # characters to write */
- int written; /* # characters actully written */
- char logname[15]; /* name of the log file(s) */
- int onalarm();
- int pipeerr();
- int wrapup();
- int grunt();
- char *malloc();
- int pvec[2]; /* for pipes */
- char *p;
- char *prog; /* my name */
-
- #if ! debug
- freopen("masterlog.00", "a", stderr);
- #endif
- fprintf(stderr, "*** New Run *** ");
- prog = argv[0];
- while (argc > 1 && argv[1][0] == '-') {
- p = &argv[1][1];
- argc--;
- argv++;
- while (*p) {
- switch (*p) {
- case 'r':
- /* code DELETED here */
- argc--;
- argv++;
- break;
-
- case 'c':
- /* code DELETED here */
- lseek(fcopy, 0L, 2); /* append at end of file */
- break;
-
- default:
- fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
- exit(4);
- }
- p++;
- }
- }
-
- if (argc < 2) {
- fprintf(stderr, "%s: missing nusers\n", prog);
- exit(4);
- }
-
- nusers = atoi(argv[1]);
- if (nusers < 1) {
- fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
- exit(4);
- }
- fprintf(stderr, "%d Users\n", nusers);
- argc--;
- argv++;
-
- /* build job streams */
- getwork();
- #if debug
- dumpwork();
- #endif
-
- /* clone copies of myself to run up to MAXCHILD jobs each */
- firstuser = MAXCHILD;
- fprintf(stderr, "master pid %d\n", getpid());
- fflush(stderr);
- while (nusers > MAXCHILD) {
- fflush(stderr);
- if (nusers >= 2*MAXCHILD)
- /* the next clone must run MAXCHILD jobs */
- nchild = MAXCHILD;
- else
- /* the next clone must run the leftover jobs */
- nchild = nusers - MAXCHILD;
- if ((l = fork()) == -1) {
- /* fork failed */
- fatal("** clone fork failed **\n");
- goto bepatient;
- } else if (l > 0) {
- fprintf(stderr, "master clone pid %d\n", l);
- /* I am the master with nchild fewer jobs to run */
- nusers -= nchild;
- firstuser += MAXCHILD;
- continue;
- } else {
- /* I am a clone, run MAXCHILD jobs */
- #if ! debug
- sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
- freopen(logname, "w", stderr);
- #endif
- master = 0;
- nusers = nchild;
- break;
- }
- }
- if (master)
- firstuser = 0;
-
- close(0);
-
- /* code DELETED here */
-
- fflush(stderr);
-
- srand(time(0));
- thres = 0;
- done = output = 0;
- for (i = 0; i < nusers; i++) {
- if (child[i].blen == 0)
- done++;
- else
- thres += est_rate * GRANULE;
- }
- est_rate = thres;
-
- signal(SIGALRM, onalarm);
- signal(SIGPIPE, pipeerr);
- alarm(GRANULE);
- while (done < nusers) {
- for (i = 0; i < nusers; i++) {
- cp = &child[i];
- if (cp->xmit >= cp->blen) continue;
- l = rand() % CHUNK + 1; /* 1-CHUNK chars */
- if (l == 0) continue;
- if (cp->xmit + l > cp->blen)
- l = cp->blen - cp->xmit;
- p = cp->bp;
- cp->bp += l;
- cp->xmit += l;
- #if debug
- fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
- #endif
- while (p < cp->bp) {
- if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
- /* write it out */
- nch = p - cp->line + 1;
- if ((written = write(cp->fd, cp->line, nch)) != nch) {
-
- /* code DELETED here */
-
- }
- if (fcopy)
- write(fcopy, cp->line, p - cp->line + 1);
- #if debug
- fprintf(stderr, "child %d gets \"", i);
- {
- char *q = cp->line;
- while (q <= p) {
- if (*q >= ' ' && *q <= '~')
- fputc(*q, stderr);
- else
- fprintf(stderr, "\\%03o", *q);
- q++;
- }
- }
- fputc('"', stderr);
- #endif
- cp->line = &p[1];
- }
- p++;
- }
- if (cp->xmit >= cp->blen) {
- done++;
- close(cp->fd);
- #if debug
- fprintf(stderr, "child %d, close std input\n", i);
- #endif
- }
- output += l;
- }
- while (output > thres) {
- pause();
- #if debug
- fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
- #endif
- }
- }
-
- bepatient:
- alarm(0);
- /****
- * If everything is going OK, we should simply be able to keep
- * looping unitil 'wait' fails, however some descendent process may
- * be in a state from which it can never exit, and so a timeout
- * is used.
- * 5 minutes should be ample, since the time to run all jobs is of
- * the order of 5-10 minutes, however some machines are painfully slow,
- * so the timeout has been set at 20 minutes (1200 seconds).
- ****/
-
- /* code DELETED here */
-
- }
-
- onalarm()
- {
- thres += est_rate;
- signal(SIGALRM, onalarm);
- alarm(GRANULE);
- }
-
- grunt()
- {
- /* timeout after label "bepatient" in main */
- exit_status = 4;
- wrapup();
- }
-
- pipeerr()
- {
- sigpipe++;
- }
-
- wrapup()
- {
- /* DUMMY, real code dropped */
- }
-
- getwork()
- {
-
- /* DUMMY, real code dropped */
- gets();
- strncpy();
- malloc(); realloc();
- open(); close();
- }
-
- fatal(s)
- char *s;
- {
- int i;
- fprintf(stderr, s);
- fflush(stderr);
- perror("Reason?");
- for (i = 0; i < nusers; i++) {
- if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1)
- fprintf(stderr, "pid %d killed off\n", child[i].pid);
- }
- fflush(stderr);
- exit_status = 4;
- return;
- }
-