sources-request@munnari.oz (09/17/87)
Submitted by: kenj@moncsbruce.oz.au (Ken McDonell)
Posting-number: Volume 11, Issue 31
Archive-name: musbus/Part03
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# grep.dat
# hanoi.c
# iamalive.c
# keyb.c
# limit.c
# log.785
# log.sun3-50
# log.uVaxII
# makework.c
# makework.h
# mem.awk
# This archive created: Thu Sep 17 06:48:15 EST 1987
export PATH; PATH=/bin:$PATH
echo 'x - grep.dat'
if test -f 'grep.dat'
then
echo 'shar: over-writing existing file grep.dat'
fi
sed 's/^X//' > grep.dat <<'End-of-File-Grunt'
X/*
X * makework -- emulate a series of terminal users
X *
X * makework [ -r rate ] [ -c copyfile ] nusers
X *
X * job streams are specified on standard input with lines of the form
X * full_path_name_for_command [ options ] [ <standard_input_file ]
X *
X * "standard input" is send to all nuser instances of the commands in the
X * job streams at a rate not in excess of "rate" characters per second
X * per command
X *
X * $Header: grep.dat,v 1.1 87/06/17 16:23:56 kjmcdonell Beta $
X */
X
X#include <stdio.h>
X#include <signal.h>
X
X#define DEF_RATE 5.0
X#define GRANULE 5
X#define CHUNK 60
X#define MAXCHILD 12
X#define MAXWORK 10
X
Xfloat thres;
Xfloat est_rate = DEF_RATE;
Xint nusers; /* number of concurrent users to be simulated by
X * this process */
Xint firstuser; /* ordinal identification of first user for this
X * process */
Xint nwork = 0; /* number of job streams */
Xint exit_status = 0; /* returned to parent */
Xint sigpipe; /* pipe write error flag */
X
Xstruct st_work {
X char *cmd; /* name of command to run */
X char **av; /* arguments to command */
X char *input; /* standard input buffer */
X int inpsize; /* size of standard input buffer */
X char *outf; /* standard output (filename) */
X} work[MAXWORK];
X
Xstruct {
X int xmit; /* # characters sent */
X char *bp; /* std input buffer pointer */
X int blen; /* std input buffer length */
X int fd; /* stdin to command */
X int pid; /* child PID */
X char *line; /* start of input line */
X int firstjob; /* inital piece of work */
X int thisjob; /* current piece of work */
X} child[MAXCHILD], *cp;
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int i;
X int l;
X int fcopy = 0; /* fd for copy output */
X int master = 1; /* the REAL master, == 0 for clones */
X int nchild; /* no. of children for a clone to run */
X int done; /* count of children finished */
X int output; /* aggregate output char count for all
X children */
X int c;
X int thiswork = 0; /* next job stream to allocate */
X int nch; /* # characters to write */
X int written; /* # characters actully written */
X char logname[15]; /* name of the log file(s) */
X int onalarm();
X int pipeerr();
X int wrapup();
X int grunt();
X int pvec[2]; /* for pipes */
X char *p;
X char *prog; /* my name */
X
X#if ! debug
X freopen("masterlog.00", "a", stderr);
X#endif
X fprintf(stderr, "*** New Run *** ");
X prog = argv[0];
X while (argc > 1 && argv[1][0] == '-') {
X p = &argv[1][1];
X argc--;
X argv++;
X while (*p) {
X switch (*p) {
X case 'r':
X est_rate = atoi(argv[1]);
X sscanf(argv[1], "%f", &est_rate);
X if (est_rate <= 0) {
X fprintf(stderr, "%s: bad rate, reset to %.2f chars/sec\n", prog, DEF_RATE);
X est_rate = DEF_RATE;
X }
X argc--;
X argv++;
X break;
X
X case 'c':
X fcopy = open(argv[1], 1);
X if (fcopy < 0)
X fcopy = creat(argv[1], 0600);
X if (fcopy < 0) {
X fprintf(stderr, "%s: cannot open copy file '%s'\n",
X prog, argv[1]);
X exit(2);
X }
X lseek(fcopy, 0L, 2); /* append at end of file */
X argc--;
X argv++;
X break;
X
X default:
X fprintf(stderr, "%s: bad flag '%c'\n", prog, *p);
X exit(4);
X }
X p++;
X }
X }
X
X if (argc < 2) {
X fprintf(stderr, "%s: missing nusers\n", prog);
X exit(4);
X }
X
X nusers = atoi(argv[1]);
X if (nusers < 1) {
X fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
X exit(4);
X }
X fprintf(stderr, "%d Users\n", nusers);
X argc--;
X argv++;
X
X /* build job streams */
X getwork();
X#if debug
X dumpwork();
X#endif
X
X /* clone copies of myself to run up to MAXCHILD jobs each */
X firstuser = MAXCHILD;
X fprintf(stderr, "master pid %d\n", getpid());
X fflush(stderr);
X while (nusers > MAXCHILD) {
X fflush(stderr);
X if (nusers >= 2*MAXCHILD)
X /* the next clone must run MAXCHILD jobs */
X nchild = MAXCHILD;
X else
X /* the next clone must run the leftover jobs */
X nchild = nusers - MAXCHILD;
X if ((l = fork()) == -1) {
X /* fork failed */
X fatal("** clone fork failed **\n");
X goto bepatient;
X } else if (l > 0) {
X fprintf(stderr, "master clone pid %d\n", l);
X /* I am the master with nchild fewer jobs to run */
X nusers -= nchild;
X firstuser += MAXCHILD;
X continue;
X } else {
X /* I am a clone, run MAXCHILD jobs */
X#if ! debug
X sprintf(logname, "masterlog.%02d", firstuser/MAXCHILD);
X freopen(logname, "w", stderr);
X#endif
X master = 0;
X nusers = nchild;
X break;
X }
X }
X if (master)
X firstuser = 0;
X
X close(0);
X for (i = 0; i < nusers; i++ ) {
X fprintf(stderr, "user %d job %d ", firstuser+i, thiswork);
X if (pipe(pvec) == -1) {
X /* this is fatal */
X fatal("** pipe failed **\n");
X goto bepatient;
X }
X fflush(stderr);
X if ((child[i].pid = fork()) == 0) {
X int fd;
X /* the command */
X if (pvec[0] != 0) {
X close(0);
X dup(pvec[0]);
X }
X#if ! debug
X sprintf(logname, "userlog.%02d", firstuser+i);
X freopen(logname, "w", stderr);
X#endif
X for (fd = 3; fd < 24; fd++)
X close(fd);
X if (work[thiswork].outf[0] != '\0') {
X /* redirect std output */
X char *q;
X for (q = work[thiswork].outf; *q != '\n'; q++) ;
X *q = '\0';
X if (freopen(work[thiswork].outf, "w", stdout) == NULL) {
X fprintf(stderr, "makework: cannot open %s for std output\n",
X work[thiswork].outf);
X fflush(stderr);
X }
X *q = '\n';
X }
X execv(work[thiswork].cmd, work[thiswork].av);
X /* don't expect to get here! */
X fatal("** exec failed **\n");
X goto bepatient;
X }
X else if (child[i].pid == -1) {
X fatal("** fork failed **\n");
X goto bepatient;
X }
X else {
X close(pvec[0]);
X child[i].fd = pvec[1];
X child[i].line = child[i].bp = work[thiswork].input;
X child[i].blen = work[thiswork].inpsize;
X child[i].thisjob = thiswork;
X child[i].firstjob = thiswork;
X fprintf(stderr, "pid %d pipe fd %d", child[i].pid, child[i].fd);
X if (work[thiswork].outf[0] != '\0') {
X char *q;
X fprintf(stderr, " > ");
X for (q=work[thiswork].outf; *q != '\n'; q++)
X fputc(*q, stderr);
X }
X fputc('\n', stderr);
X thiswork++;
X if (thiswork >= nwork)
X thiswork = 0;
X }
X }
X fflush(stderr);
X
X srand(time(0));
X thres = 0;
X done = output = 0;
X for (i = 0; i < nusers; i++) {
X if (child[i].blen == 0)
X done++;
X else
X thres += est_rate * GRANULE;
X }
X est_rate = thres;
X
X signal(SIGALRM, onalarm);
X signal(SIGPIPE, pipeerr);
X alarm(GRANULE);
X while (done < nusers) {
X for (i = 0; i < nusers; i++) {
X cp = &child[i];
X if (cp->xmit >= cp->blen) continue;
X l = rand() % CHUNK + 1; /* 1-CHUNK chars */
X if (l == 0) continue;
X if (cp->xmit + l > cp->blen)
X l = cp->blen - cp->xmit;
X p = cp->bp;
X cp->bp += l;
X cp->xmit += l;
X#if debug
X fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
X#endif
X while (p < cp->bp) {
X if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
X /* write it out */
X nch = p - cp->line + 1;
X if ((written = write(cp->fd, cp->line, nch)) != nch) {
X /* argh! */
X cp->line[nch] = '\0';
X fprintf(stderr, "user %d job %d cmd %s ",
X firstuser+i, cp->thisjob, cp->line);
X fprintf(stderr, "write(,,%d) returns %d\n", nch, written);
X if (sigpipe)
X fatal("** SIGPIPE error **\n");
X else
X fatal("** write error **\n");
X goto bepatient;
X
X }
X if (fcopy)
X write(fcopy, cp->line, p - cp->line + 1);
X#if debug
X fprintf(stderr, "child %d gets \"", i);
X {
X char *q = cp->line;
X while (q <= p) {
X if (*q >= ' ' && *q <= '~')
X fputc(*q, stderr);
X else
X fprintf(stderr, "\\%03o", *q);
X q++;
X }
X }
X fputc('"', stderr);
X#endif
X cp->line = &p[1];
X }
X p++;
X }
X if (cp->xmit >= cp->blen) {
X done++;
X close(cp->fd);
X#if debug
X fprintf(stderr, "child %d, close std input\n", i);
X#endif
X }
X output += l;
X }
X while (output > thres) {
X pause();
X#if debug
X fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
X#endif
X }
X }
X
Xbepatient:
X alarm(0);
X/****
X * If everything is going OK, we should simply be able to keep
X * looping unitil 'wait' fails, however some descendent process may
X * be in a state from which it can never exit, and so a timeout
X * is used.
X * 5 minutes should be ample, since the time to run all jobs is of
X * the order of 5-10 minutes, however some machines are painfully slow,
X * so the timeout has been set at 20 minutes (1200 seconds).
X ****/
X signal(SIGALRM, grunt);
X alarm(1200);
X while ((c = wait(&l)) != -1) {
X for (i = 0; i < nusers; i++) {
X if (c == child[i].pid) {
X fprintf(stderr, "user %d job %d pid %d done", firstuser+i, child[i].thisjob, c);
X if (l != 0) {
X if (l & 0x7f)
X fprintf(stderr, " status %d", l & 0x7f);
X if (l & 0xff00)
X fprintf(stderr, " exit code %d", (l>>8) & 0xff);
X exit_status = 4;
X }
X fputc('\n', stderr);
X c = child[i].pid = -1;
X break;
X }
X }
X if (c != -1) {
X fprintf(stderr, "master clone done, pid %d ", c);
X if (l != 0) {
X if (l & 0x7f)
X fprintf(stderr, " status %d", l & 0x7f);
X if (l & 0xff00)
X fprintf(stderr, " exit code %d", (l>>8) & 0xff);
X exit_status = 4;
X }
X fputc('\n', stderr);
X }
X }
X alarm(0);
X wrapup("Finished waiting ...");
X
X
X}
X
Xonalarm()
X{
X thres += est_rate;
X signal(SIGALRM, onalarm);
X alarm(GRANULE);
X}
X
Xgrunt()
X{
X /* timeout after label "bepatient" in main */
X exit_status = 4;
X wrapup("Timed out waiting for jobs to finish ...");
X}
X
Xpipeerr()
X{
X sigpipe++;
X}
X
Xwrapup(reason)
Xchar *reason;
X{
X int i;
X int killed = 0;
X fflush(stderr);
X for (i = 0; i < nusers; i++) {
X if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1) {
X if (!killed) {
X killed++;
X fprintf(stderr, "%s\n", reason);
X fflush(stderr);
X }
X fprintf(stderr, "user %d job %d pid %d killed off\n", firstuser+i, child[i].thisjob, child[i].pid);
X fflush(stderr);
X }
X }
X exit(exit_status);
X}
X
Xgetwork()
X{
X int i;
X int f;
X int ac;
X char *lp;
X char *q;
X struct st_work *w;
X char line[512];
X char c;
X char *malloc(), *realloc();
X
X while (gets(line) != NULL) {
X if (nwork >= MAXWORK) {
X fprintf(stderr, stderr, "Too many jobs specified, .. increase MAXWORK\n");
X exit(4);
X }
X w = &work[nwork];
X lp = line;
X i = 1;
X while (*lp && *lp != ' ') {
X i++;
X lp++;
X }
X w->cmd = (char *)malloc(i);
X strncpy(w->cmd, line, i-1);
X w->cmd[i-1] = '\0';
X w->inpsize = 0;
X w->input = "";
X /* start to build arg list */
X ac = 2;
X w->av = (char **)malloc(2*sizeof(char *));
X q = w->cmd;
X while (*q) q++;
X q--;
X while (q >= w->cmd) {
X if (*q == '/') {
X q++;
X break;
X }
X q--;
X }
X w->av[0] = q;
X while (*lp) {
X if (*lp == ' ') {
X /* space */
X lp++;
X continue;
X }
X else if (*lp == '<') {
X /* standard input for this job */
X q = ++lp;
X while (*lp && *lp != ' ') lp++;
X c = *lp;
X *lp = '\0';
X if ((f = open(q, 0)) == -1) {
X fprintf(stderr, "cannot open input file (%s) for job %d\n",
X q, nwork);
X exit(4);
X }
X /* gobble input */
X w->input = (char *)malloc(512);
X while ((i = read(f, &w->input[w->inpsize], 512)) > 0) {
X w->inpsize += i;
X w->input = (char *)realloc(w->input, w->inpsize+512);
X }
X w->input = (char *)realloc(w->input, w->inpsize);
X close(f);
X /* extract stdout file name from line beginning "C=" */
X w->outf = "";
X for (q = w->input; q < &w->input[w->inpsize-10]; q++) {
X if (*q == '\n' && strncmp(&q[1], "C=", 2) == 0) {
X w->outf = &q[3];
X break;
X }
X }
X#if debug
X if (*w->outf) {
X fprintf(stderr, "stdout->");
X for (q=w->outf; *q != '\n'; q++)
X fputc(*q, stderr);
X fputc('\n', stderr);
X }
X#endif
X }
X else {
X /* a command option */
X ac++;
X w->av = (char **)realloc(w->av, ac*sizeof(char *));
X q = lp;
X i = 1;
X while (*lp && *lp != ' ') {
X lp++;
X i++;
X }
X w->av[ac-2] = (char *)malloc(i);
X strncpy(w->av[ac-2], q, i-1);
X w->av[ac-2][i-1] = '\0';
X }
X }
X w->av[ac-1] = (char *)0;
X nwork++;
X }
X}
X
X#if debug
Xdumpwork()
X{
X int i;
X int j;
X
X for (i = 0; i < nwork; i++) {
X fprintf(stderr, "job %d: cmd: %s\n", i, work[i].cmd);
X j = 0;
X while (work[i].av[j]) {
X fprintf(stderr, "argv[%d]: %s\n", j, work[i].av[j]);
X j++;
X }
X fprintf(stderr, "input: %d chars text: ", work[i].inpsize);
X if (work[i].input == (char *)0)
X fprintf(stderr, "<NULL>\n");
X else {
X register char *pend;
X char *p;
X char c;
X p = work[i].input;
X while (*p) {
X pend = p;
X while (*pend && *pend != '\n')
X pend++;
X c = *pend;
X *pend = '\0';
X fprintf(stderr, "%s\n", p);
X *pend = c;
X p = &pend[1];
X }
X }
X }
X}
X#endif
X
Xfatal(s)
Xchar *s;
X{
X int i;
X fprintf(stderr, s);
X fflush(stderr);
X perror("Reason?");
X fflush(stderr);
X for (i = 0; i < nusers; i++) {
X if (child[i].pid > 0 && kill(child[i].pid, SIGKILL) != -1) {
X fprintf(stderr, "pid %d killed off\n", child[i].pid);
X fflush(stderr);
X }
X }
X exit_status = 4;
X return;
X}
End-of-File-Grunt
if test 13130 -ne `cat 'grep.dat' | wc -c`
then
echo 'shar: transmission error (expected 13130 characters)'
fi
echo 'x - hanoi.c'
if test -f 'hanoi.c'
then
echo 'shar: over-writing existing file hanoi.c'
fi
sed 's/^X//' > hanoi.c <<'End-of-File-Grunt'
X/*
X * $Header: hanoi.c,v 3.5 87/08/06 08:11:14 kenj Exp $
X */
X#define PRINT 0
X#define DISK 3
X#define other(i,j) (6-(i+j))
Xint num[4];
Xlong cnt;
Xmain(argc,argv)
Xchar **argv;
X{
X int disk;
X disk = DISK;
X if(argc > 1)disk = atoi(argv[1]);
X num[1] = disk;
X if(PRINT)printf("Start %d on A\n",disk);
X mov(disk,1,3);
X printf("For %d disks, %ld moves\n",disk,cnt);
X
X exit(0);
X}
X
Xmov(n,f,t)
X{
X int o;
X if(n == 1) {
X num[f]--;
X num[t]++;
X if(PRINT)printf("Move from %d to %d, result: A:%d B:%d C%d\n",
X f,t,num[1],num[2],num[3]);
X cnt++;
X return;
X }
X o = other(f,t);
X mov(n-1,f,o);
X mov(1,f,t);
X mov(n-1,o,t);
X return;
X}
End-of-File-Grunt
if test 619 -ne `cat 'hanoi.c' | wc -c`
then
echo 'shar: transmission error (expected 619 characters)'
fi
echo 'x - iamalive.c'
if test -f 'iamalive.c'
then
echo 'shar: over-writing existing file iamalive.c'
fi
sed 's/^X//' > iamalive.c <<'End-of-File-Grunt'
X/*
X * echo argv[1] without \n, to tell user we are still alive
X *
X * $Header: iamalive.c,v 3.4 87/06/22 14:23:22 kjmcdonell Beta $
X */
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X if (argc == 2)
X printf("%s ", argv[1]);
X exit(0);
X}
End-of-File-Grunt
if test 233 -ne `cat 'iamalive.c' | wc -c`
then
echo 'shar: transmission error (expected 233 characters)'
fi
echo 'x - keyb.c'
if test -f 'keyb.c'
then
echo 'shar: over-writing existing file keyb.c'
fi
sed 's/^X//' > keyb.c <<'End-of-File-Grunt'
X/*
X * keyb -- emulate a user typing at a terminal
X *
X * keyb [ datafile ]
X *
X * standard input is copied to standard output at a rate not in excess
X * of "rate" characters per second, and copied to "copyfile" if
X * specified
X *
X * environment variables $rate and $tty control typing rate (characters
X * per second) and destination of echoed output.
X *
X * $Header: keyb.c,v 3.5 87/06/22 14:24:28 kjmcdonell Beta $
X */
X
X#include <stdio.h>
X#include <signal.h>
X
X#define DEF_RATE 5
X#define GRANULE 5
X
Xint thres;
Xint est_rate = DEF_RATE;
Xint sigpipe; /* pipe write error flag */
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int i;
X int l;
X int fcopy = 0; /* fd for copy output */
X int output; /* aggregate output char count */
X int c;
X int nch; /* # characters read */
X char buf[16]; /* the current glob of data */
X int onalarm();
X int pipeerr();
X char *getenv();
X int written;
X char *p;
X char *prog; /* my name */
X
X prog = argv[0];
X if ((p = getenv("rate")) != (char *)0) {
X sscanf(p, "%f", &est_rate);
X if (est_rate <= 0) {
X fprintf(stderr, "%s: bad rate, reset to %.2f chars/sec\n", prog, DEF_RATE);
X est_rate = DEF_RATE;
X }
X#ifdef DEBUG
X else
X fprintf(stderr, "%s: typing rate %.2f chars/sec\n", est_rate);
X#endif
X }
X if ((p = getenv("tty")) != (char *)0) {
X fcopy = open(p, 1);
X if (fcopy < 0)
X fcopy = creat(p, 0600);
X if (fcopy < 0) {
X fprintf(stderr, "%s: cannot open copy file '%s'\n", prog, p);
X exit(2);
X }
X lseek(fcopy, 0L, 2); /* append at end of file */
X }
X
X if (argc == 2) {
X /* datafile argument specified */
X close(0);
X if (open(argv[1], 0) < 0) {
X fprintf(stderr, "%s: Cannot open %s\n", prog, argv[1]);
X exit(4);
X }
X }
X
X srand(time(0));
X thres = est_rate = est_rate * GRANULE;
X output = 0;
X
X signal(SIGPIPE, pipeerr);
X signal(SIGALRM, onalarm);
X alarm(GRANULE);
X while (1) {
X l = rand() % 15 + 1; /* 1-15 chars */
X if (l == 0) continue;
X nch = read(0, buf, l);
X if (nch == 0)
X break;
X if ((written = write(1, buf, nch)) != nch) {
X /* argh! */
X if (sigpipe)
X fprintf(stderr, "type: ** SIGPIPE error ** buf: %s\n", buf);
X else
X fprintf(stderr, "type: ** write error ** buf: %s\n", buf);
X exit(4);
X }
X if (fcopy)
X write(fcopy, buf, nch);
X output += nch;
X while (output > thres)
X pause();
X }
X alarm(0);
X exit(0);
X}
X
Xonalarm()
X{
X thres += est_rate;
X signal(SIGALRM, onalarm);
X alarm(GRANULE);
X}
X
Xpipeerr()
X{
X sigpipe++;
X}
End-of-File-Grunt
if test 2513 -ne `cat 'keyb.c' | wc -c`
then
echo 'shar: transmission error (expected 2513 characters)'
fi
echo 'x - limit.c'
if test -f 'limit.c'
then
echo 'shar: over-writing existing file limit.c'
fi
sed 's/^X//' > limit.c <<'End-of-File-Grunt'
X/*
X * Force a UNIX system to the per process and per user limits
X *
X * $Header: limit.c,v 3.4 87/06/22 14:25:11 kjmcdonell Beta $
X */
X
X#define CLICK 1024
X#define MAXCHN 100
X
X#include <signal.h>
X#include <setjmp.h>
X
Xint parent; /* parent's pid */
Xint child; /* child's pid */
Xint pid[MAXCHN];
Xint ncall;
Xint level;
Xjmp_buf env;
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X char *top;
X int pad;
X int end;
X int i;
X int status;
X float f;
X int flag();
X int wakeup();
X long last;
X
X /* open files (file descriptors) */
X for (i = 3; open(".", 0) > 0; i++) ;
X printf("Maximum open files per process: %d\n", i);
X while (--i > 2)
X close(i);
X
X /* process address space */
X top = (char *)sbrk(0);
X#if debug
X printf("inital top of program: 0x%x\n", top);
X#endif
X pad = (((int)top+CLICK-1)/CLICK)*CLICK - (int)top;
X sbrk(pad);
X for (i = 0; (char *)sbrk(CLICK) != (char *)-1; i++) ;
X#if debug
X printf("final top of program: 0x%x\n", sbrk(0));
X#endif
X brk(top);
X#if debug
X printf("top of program restored to: 0x%x\n", sbrk(0));
X#endif
X end = (((int)top+pad)/CLICK) + i;
X f = ((float)end * CLICK) / 1024;
X printf("Process address space limit: ");
X if (f < 1024)
X printf("%.2f Kbytes\n", f);
X else {
X f /= 1024;
X printf("%.2f Mbytes\n", f);
X }
X
X /* process creations */
X printf("Maximum number of child processes:");
X i = 0;
X while (1) {
X#if debug
X printf("about to fork\n");
X#endif
X if ((pid[i] = fork()) == -1) {
X#if debug
X perror("fork failed");
X#endif
X break;
X } else if (pid[i] != 0) {
X#if debug
X printf("child %d: pid=%d\n", i+1, pid[i]);
X#endif
X i++;
X if (i >= MAXCHN) {
X printf(" more than");
X break;
X }
X } else {
X#if debug
X printf("child %d pausing\n", getpid());
X#endif
X pause();
X#if debug
X printf("child %d exiting\n", getpid());
X#endif
X exit(1);
X }
X }
X printf(" %d\n", i);
X while (--i >= 0) {
X kill(pid[i], SIGKILL);
X wait(0);
X }
X
X ncall = level = 0;
X parent = getpid();
X signal(SIGTERM, flag);
X if ((child = fork()) == 0) {
X signal(SIGALRM, wakeup);
X recurse();
X exit(4);
X }
X while ((i = wait(&status)) == -1) {
X }
X printf("Estimated maximum stack size: %d Kbytes\n", level);
X exit(0);
X}
X
Xrecurse()
X{
X int temp[1024 / sizeof(int)];
X#if debug
X printf("recursion @ level %d\n", ncall);
X#endif
X temp[1024 / sizeof(int) - 1] = 1;
X ncall++;
X kill(parent, SIGTERM);
X while (ncall > level) {
X alarm(2);
X pause();
X }
X if (ncall < 8000)
X /* less than 8M bytes of temp storage! */
X recurse();
X else
X /* give up! */
X exit(0);
X}
X
Xflag()
X{
X signal(SIGTERM, flag);
X level++;
X if (child != 0)
X kill(child, SIGTERM);
X}
X
Xwakeup()
X{
X signal(SIGALRM, wakeup);
X}
End-of-File-Grunt
if test 2588 -ne `cat 'limit.c' | wc -c`
then
echo 'shar: transmission error (expected 2588 characters)'
fi
echo 'x - log.785'
if test -f 'log.785'
then
echo 'shar: over-writing existing file log.785'
fi
sed 's/^X//' > log.785 <<'End-of-File-Grunt'
X
XMC="VAX 11/785"
XOPT="FPA"
XMEM="8 Mbytes"
XUNIX="BSD 4.3 "
XDISKS="2 x RA81"
X
XStart Benchmark Run (MUSBUS Version 5.0.Beta)
X Mon Jun 22 17:37:44 EDT 1987 (long iterations 6 times)
X 11 interactive users.
X
XArithmetic Test (type = arithoh): 1000 Iterations
XElapsed Time: 0.35 seconds (variance 0.007)
XCPU Time: 0.22 seconds [ 0.22u + 0.00s ] (variance 0.002)
X
XArithmetic Test (type = register): 1000 Iterations
XElapsed Time: 1.47 seconds (variance 0.011) (Actual: 1.12 )
XCPU Time: 1.12 seconds [ 1.12u + 0.00s ] (variance 0.002) (Actual: 0.90 )
X
XArithmetic Test (type = short): 1000 Iterations
XElapsed Time: 1.98 seconds (variance 0.022) (Actual: 1.63 )
XCPU Time: 1.70 seconds [ 1.70u + 0.00s ] (variance -0.000) (Actual: 1.48 )
X
XArithmetic Test (type = int): 1000 Iterations
XElapsed Time: 1.50 seconds (variance 0.008) (Actual: 1.15 )
XCPU Time: 1.30 seconds [ 1.30u + 0.00s ] (variance -0.000) (Actual: 1.08 )
X
XArithmetic Test (type = long): 1000 Iterations
XElapsed Time: 1.78 seconds (variance 0.078) (Actual: 1.43 )
XCPU Time: 1.35 seconds [ 1.33u + 0.02s ] (variance 0.003) (Actual: 1.13 )
X
XArithmetic Test (type = float): 1000 Iterations
XElapsed Time: 2.98 seconds (variance 0.726) (Actual: 2.63 )
XCPU Time: 2.43 seconds [ 2.40u + 0.03s ] (variance 0.003) (Actual: 2.21 )
X
XArithmetic Test (type = double): 1000 Iterations
XElapsed Time: 3.70 seconds (variance 1.016) (Actual: 3.35 )
XCPU Time: 2.37 seconds [ 2.30u + 0.07s ] (variance 0.011) (Actual: 2.15 )
X
XArithmetic Test (sqrt(2) with dc to 99 decimal places)
XElapsed Time: 2.43 seconds (variance 1.051)
XCPU Time: 1.45 seconds [ 1.33u + 0.12s ] (variance 0.007)
X
XRecursion Test: Tower of Hanoi Problem
X
X17 Disk Problem:
XElapsed Time: 5.42 seconds (variance 2.230)
XCPU Time: 4.30 seconds [ 4.20u + 0.10s ] (variance 0.008)
X
XSystem Call Overhead Test: 5 x 4000 Calls
XElapsed Time: 3.97 seconds (variance 0.243)
XCPU Time: 3.23 seconds [ 0.35u + 2.88s ] (variance 0.007)
X
XPipe Throughput Test: read & write 2048 x 512 byte blocks
XElapsed Time: 3.60 seconds (variance 0.020)
XCPU Time: 3.08 seconds [ 0.03u + 3.05s ] (variance 0.006)
X
XPipe-based Context Switching Test: 2 x 500 Switches
XElapsed Time: 1.57 seconds (variance 0.015)
XCPU Time: 0.70 seconds [ 0.05u + 0.65s ] (variance -0.000)
X
XProcess Creation Test: 100 forks
XElapsed Time: 1.93 seconds (variance 0.387)
XCPU Time: 1.45 seconds [ 0.00u + 1.45s ] (variance 0.003)
X
XExecl Throughput Test: 100 execs
XElapsed Time: 5.90 seconds (variance 28.036)
XCPU Time: 2.35 seconds [ 0.00u + 2.35s ] (variance 0.007)
X
XC Compiler Test:
X
Xcc -c cctest.c
XElapsed Time: 4.10 seconds (variance 0.130)
XCPU Time: 2.53 seconds [ 1.73u + 0.80s ] (variance 0.003)
X
Xcc cctest.o
XElapsed Time: 1.73 seconds (variance 0.303)
XCPU Time: 0.70 seconds [ 0.20u + 0.50s ] (variance 0.010)
X
XSequential Memory Access Test: 100000 Accesses
X
XArray Size: 8 Kbytes
X** Iteration 2 real loop < ohead: 100000 -478 0.017
XElapsed Time: 0.16 seconds (variance 0.015)
XCPU Time: 0.11 seconds (variance 0.003)
XReal Rate: 613497 int array accesses / second
X
XArray Size: 64 Kbytes
XElapsed Time: 0.19 seconds (variance 0.005)
XCPU Time: 0.17 seconds (variance 0.001)
XReal Rate: 528634 int array accesses / second
X
XArray Size: 512 Kbytes
X** Iteration 4 real loop < ohead: 100000 -461 0.200
XElapsed Time: 0.36 seconds (variance 0.051)
XCPU Time: 0.29 seconds (variance 0.002)
XReal Rate: 278552 int array accesses / second
X
XRandom Memory Access Test: 100000 Accesses
X
XArray Size: 8 Kbytes
XElapsed Time: 0.15 seconds (variance 0.001)
XCPU Time: 0.15 seconds (variance 0.001)
XReal Rate: 667408 int array accesses / second
X
XArray Size: 64 Kbytes
XElapsed Time: 0.18 seconds (variance 0.003)
XCPU Time: 0.18 seconds (variance 0.000)
XReal Rate: 555042 int array accesses / second
X
XArray Size: 512 Kbytes
XElapsed Time: 0.32 seconds (variance 0.001)
XCPU Time: 0.33 seconds (variance 0.000)
XReal Rate: 309917 int array accesses / second
X
XFilesystem Throughput Test:
X
XFile Size: 62 blocks
XWrite: 221.4 Kbytes per second (variance 2919.0)
XRead: 181.6 Kbytes per second (variance 1253.2)
XCopy: 62.4 Kbytes per second (variance 130.2)
X
XFile Size: 125 blocks
XWrite: 252.0 Kbytes per second (variance 919.1)
XRead: 151.9 Kbytes per second (variance 230.7)
XCopy: 80.9 Kbytes per second (variance 66.2)
X
XFile Size: 250 blocks
XWrite: 300.1 Kbytes per second (variance 2511.2)
XRead: 170.1 Kbytes per second (variance 173.9)
XCopy: 71.1 Kbytes per second (variance 44.4)
X
XFile Size: 500 blocks
XWrite: 338.7 Kbytes per second (variance 375.2)
XRead: 178.2 Kbytes per second (variance 541.2)
XCopy: 86.1 Kbytes per second (variance 43.5)
X
X
XOutput sent to ... /dev/ttyh0
XDirectories for temporary files ... Tmp
X
XFilesystem kbytes used avail capacity Mounted on
X/dev/ra0a 7429 4997 1689 75% /
X/dev/ra0g 38879 672 34319 2% /tmp
X/dev/ra0h 361860 286238 39436 88% /usr
X/dev/ra1g 38879 33960 1031 97% /backup
X/dev/ra1h 361860 273307 52367 84% /u
X
XSIGALRM check: 12 x 5 sec delays takes 60.04 wallclock secs (error -0.06%)
XSimulated Multi-user Work Load Test:
X
X1 Concurrent Users, each with Input Keyboard Rate 2 chars / sec
XElapsed Time: 391.10 seconds (variance 0.656)
XCPU Time: 15.67 seconds [ 9.10u + 6.57s ] (variance 0.503)
X
X4 Concurrent Users, each with Input Keyboard Rate 2 chars / sec
XElapsed Time: 392.73 seconds (variance 0.281)
XCPU Time: 61.37 seconds [ 37.07u + 24.30s ] (variance 1.853)
X
X8 Concurrent Users, each with Input Keyboard Rate 2 chars / sec
XElapsed Time: 395.17 seconds (variance 3.797)
XCPU Time: 125.30 seconds [ 75.33u + 49.97s ] (variance 0.092)
X
X 15 interactive users.
XEnd Benchmark Run (Tue Jun 23 08:50:34 EDT 1987) ....
End-of-File-Grunt
if test 5694 -ne `cat 'log.785' | wc -c`
then
echo 'shar: transmission error (expected 5694 characters)'
fi
echo 'x - log.sun3-50'
if test -f 'log.sun3-50'
then
echo 'shar: over-writing existing file log.sun3-50'
fi
sed 's/^X//' > log.sun3-50 <<'End-of-File-Grunt'
X
XMC="Sun 3/50"
XOPT=""
XMEM="4 Mbytes"
XUNIX="Sun OS 3.2 +4.3BSD"
XDISKS="Sun 3/180 NFS server, 8 Mb, 2 Eagles, Zylogics controller"
X
XStart Benchmark Run (MUSBUS Version 5.0.Beta)
X Wed Jun 24 14:55:15 EDT 1987 (long iterations 6 times)
X 1 interactive users.
X
XArithmetic Test (type = arithoh): 1000 Iterations
XElapsed Time: 0.32 seconds (variance 0.002)
XCPU Time: 0.22 seconds [ 0.20u + 0.02s ] (variance 0.002)
X
XArithmetic Test (type = register): 1000 Iterations
XElapsed Time: 1.32 seconds (variance 0.002)
XCPU Time: 1.22 seconds [ 1.20u + 0.02s ] (variance 0.002)
X
XArithmetic Test (type = short): 1000 Iterations
XElapsed Time: 1.55 seconds (variance 0.007)
XCPU Time: 1.42 seconds [ 1.40u + 0.02s ] (variance 0.002)
X
XArithmetic Test (type = int): 1000 Iterations
XElapsed Time: 1.62 seconds (variance 0.010)
XCPU Time: 1.52 seconds [ 1.50u + 0.02s ] (variance 0.002)
X
XArithmetic Test (type = long): 1000 Iterations
XElapsed Time: 1.58 seconds (variance 0.006)
XCPU Time: 1.48 seconds [ 1.47u + 0.02s ] (variance 0.002)
X
XArithmetic Test (type = float): 1000 Iterations
XElapsed Time: 41.70 seconds (variance 0.560)
XCPU Time: 40.98 seconds [ 40.78u + 0.20s ] (variance 0.026)
X
XArithmetic Test (type = double): 1000 Iterations
XElapsed Time: 37.03 seconds (variance 0.023)
XCPU Time: 36.72 seconds [ 36.57u + 0.15s ] (variance 0.006)
X
XArithmetic Test (sqrt(2) with dc to 99 decimal places)
XElapsed Time: 1.65 seconds (variance 0.007)
XCPU Time: 1.50 seconds [ 1.37u + 0.13s ] (variance 0.000)
X
XRecursion Test: Tower of Hanoi Problem
X
X17 Disk Problem:
XElapsed Time: 2.13 seconds (variance 0.003)
XCPU Time: 2.03 seconds [ 2.00u + 0.03s ] (variance 0.003)
X
XSystem Call Overhead Test: 5 x 4000 Calls
XElapsed Time: 3.65 seconds (variance 0.007)
XCPU Time: 3.53 seconds [ 0.53u + 3.00s ] (variance 0.007)
X
XPipe Throughput Test: read & write 2048 x 512 byte blocks
XElapsed Time: 6.02 seconds (variance 0.014)
XCPU Time: 5.88 seconds [ 0.10u + 5.78s ] (variance 0.002)
X
XPipe-based Context Switching Test: 2 x 500 Switches
XElapsed Time: 1.63 seconds (variance 0.007)
XCPU Time: 0.80 seconds [ 0.00u + 0.80s ] (variance 0.012)
X
XProcess Creation Test: 100 forks
XElapsed Time: 2.65 seconds (variance 0.015)
XCPU Time: 2.50 seconds [ 0.02u + 2.48s ] (variance 0.000)
X
XExecl Throughput Test: 100 execs
XElapsed Time: 6.93 seconds (variance 0.019)
XCPU Time: 6.07 seconds [ 0.00u + 6.07s ] (variance 0.007)
X
XC Compiler Test:
X
Xcc -c cctest.c
XElapsed Time: 7.13 seconds (variance 0.103)
XCPU Time: 3.13 seconds [ 1.97u + 1.17s ] (variance 0.003)
X
Xcc cctest.o
XElapsed Time: 3.53 seconds (variance 0.103)
XCPU Time: 0.80 seconds [ 0.33u + 0.47s ] (variance 0.030)
X
XSequential Memory Access Test: 100000 Accesses
X
XArray Size: 8 Kbytes
XElapsed Time: 0.12 seconds (variance 0.000)
XCPU Time: 0.14 seconds (variance 0.000)
XReal Rate: 810811 int array accesses / second
X
XArray Size: 64 Kbytes
X** Iteration 6 real loop < ohead: 100000 -500 0.167
XElapsed Time: 0.32 seconds (variance 0.104)
XCPU Time: 0.15 seconds (variance 0.001)
XReal Rate: 309438 int array accesses / second
X
XArray Size: 512 Kbytes
XElapsed Time: 0.17 seconds (variance 0.002)
XCPU Time: 0.18 seconds (variance 0.001)
XReal Rate: 588235 int array accesses / second
X
XRandom Memory Access Test: 100000 Accesses
X
XArray Size: 8 Kbytes
XElapsed Time: 0.22 seconds (variance 0.000)
XCPU Time: 0.22 seconds (variance 0.000)
XReal Rate: 448430 int array accesses / second
X
XArray Size: 64 Kbytes
XElapsed Time: 0.28 seconds (variance 0.009)
XCPU Time: 0.25 seconds (variance 0.001)
XReal Rate: 357782 int array accesses / second
X
XArray Size: 512 Kbytes
XElapsed Time: 0.32 seconds (variance 0.021)
XCPU Time: 0.27 seconds (variance 0.005)
XReal Rate: 316289 int array accesses / second
X
XFilesystem Throughput Test:
X
XFile Size: 62 blocks
XWrite: 69.3 Kbytes per second (variance 383.2)
XRead: 227.1 Kbytes per second (variance 96.7)
XCopy: 76.3 Kbytes per second (variance 8.4)
X
XFile Size: 125 blocks
XWrite: 66.8 Kbytes per second (variance 6.3)
XRead: 237.4 Kbytes per second (variance 26.4)
XCopy: 61.6 Kbytes per second (variance 13.1)
X
XFile Size: 250 blocks
XWrite: 59.4 Kbytes per second (variance 3.8)
XRead: 238.9 Kbytes per second (variance 6.8)
XCopy: 52.4 Kbytes per second (variance 5.7)
X
XFile Size: 500 blocks
XWrite: 45.5 Kbytes per second (variance 14.0)
XRead: 243.5 Kbytes per second (variance 1.9)
XCopy: 28.8 Kbytes per second (variance 74.5)
X
X
XOutput sent to ... /dev/console
XDirectories for temporary files ... Tmp
X
XFilesystem kbytes used avail capacity Mounted on
X/dev/nd0 3859 2795 678 80% /
X/dev/ndp1 8639 3856 3919 50% /pub
Xlily-lilynet:/ 7735 4764 2197 68% /server_root
Xlily-lilynet:/u 278443 188883 61715 75% /u
Xlily-lilynet:/usr 161167 142089 2961 98% /usr
Xlily-lilynet:/usr/private/lily13
X 161167 142089 2961 98% /private_nfs
X
XSIGALRM check: 12 x 5 sec delays takes 60.00 wallclock secs (error 0.00%)
XSimulated Multi-user Work Load Test:
X
X1 Concurrent Users, each with Input Keyboard Rate 2 chars / sec
XElapsed Time: 359.70 seconds (variance 29.656)
XCPU Time: 20.17 seconds [ 8.33u + 11.83s ] (variance 0.163)
X
X4 Concurrent Users, each with Input Keyboard Rate 2 chars / sec
XElapsed Time: 361.23 seconds (variance 18.906)
XCPU Time: 89.73 seconds [ 34.37u + 55.37s ] (variance 1.201)
X
X8 Concurrent Users, each with Input Keyboard Rate 2 chars / sec
XElapsed Time: 374.20 seconds (variance 348.797)
XCPU Time: 189.17 seconds [ 69.17u + 120.00s ] (variance 1.023)
X
X 1 interactive users.
XEnd Benchmark Run (Wed Jun 24 14:55:15 EDT 1987) ....
End-of-File-Grunt
if test 5641 -ne `cat 'log.sun3-50' | wc -c`
then
echo 'shar: transmission error (expected 5641 characters)'
fi
echo 'x - log.uVaxII'
if test -f 'log.uVaxII'
then
echo 'shar: over-writing existing file log.uVaxII'
fi
sed 's/^X//' > log.uVaxII <<'End-of-File-Grunt'
X
XMC="uVaxII (VaxStation II/GPX)"
XOPT="FP unit"
XMEM="3 Mbytes"
XUNIX="Ultrix 1.2"
XDISKS="RD53"
X
XStart Benchmark Run (MUSBUS Version 5.0.Beta)
X Tue Jun 23 17:18:21 EDT 1987 (long iterations 6 times)
X 2 interactive users.
X
XArithmetic Test (type = arithoh): 1000 Iterations
XElapsed Time: 0.52 seconds (variance 0.002)
XCPU Time: 0.37 seconds [ 0.37u + 0.00s ] (variance 0.003)
X
XArithmetic Test (type = register): 1000 Iterations
XElapsed Time: 2.15 seconds (variance 0.051) (Actual: 1.63 )
XCPU Time: 1.92 seconds [ 1.90u + 0.02s ] (variance 0.002) (Actual: 1.55 )
X
XArithmetic Test (type = short): 1000 Iterations
XElapsed Time: 3.12 seconds (variance 0.114) (Actual: 2.60 )
XCPU Time: 2.83 seconds [ 2.80u + 0.03s ] (variance 0.003) (Actual: 2.46 )
X
XArithmetic Test (type = int): 1000 Iterations
XElapsed Time: 2.45 seconds (variance 0.003) (Actual: 1.93 )
XCPU Time: 2.30 seconds [ 2.30u + 0.00s ] (variance 0.000) (Actual: 1.93 )
X
XArithmetic Test (type = long): 1000 Iterations
XElapsed Time: 2.48 seconds (variance 0.006) (Actual: 1.96 )
XCPU Time: 2.30 seconds [ 2.28u + 0.02s ] (variance 0.004) (Actual: 1.93 )
X
XArithmetic Test (type = float): 1000 Iterations
XElapsed Time: 5.13 seconds (variance 0.031) (Actual: 4.61 )
XCPU Time: 4.82 seconds [ 4.80u + 0.02s ] (variance 0.002) (Actual: 4.45 )
X
XArithmetic Test (type = double): 1000 Iterations
XElapsed Time: 3.97 seconds (variance 0.015) (Actual: 3.45 )
XCPU Time: 3.72 seconds [ 3.70u + 0.02s ] (variance 0.002) (Actual: 3.35 )
X
XArithmetic Test (sqrt(2) with dc to 99 decimal places)
XElapsed Time: 2.92 seconds (variance 0.086)
XCPU Time: 2.53 seconds [ 2.40u + 0.13s ] (variance 0.003)
X
XRecursion Test: Tower of Hanoi Problem
X
X17 Disk Problem:
XElapsed Time: 5.20 seconds (variance 0.008)
XCPU Time: 4.97 seconds [ 4.93u + 0.03s ] (variance 0.007)
X
XSystem Call Overhead Test: 5 x 4000 Calls
XElapsed Time: 5.55 seconds (variance 0.055)
XCPU Time: 5.28 seconds [ 0.75u + 4.53s ] (variance 0.002)
X
XPipe Throughput Test: read & write 2048 x 512 byte blocks
XElapsed Time: 4.12 seconds (variance 0.010)
XCPU Time: 3.92 seconds [ 0.12u + 3.80s ] (variance 0.002)
X
XPipe-based Context Switching Test: 2 x 500 Switches
XElapsed Time: 2.13 seconds (variance 0.031)
XCPU Time: 0.90 seconds [ 0.03u + 0.87s ] (variance 0.004)
X
XProcess Creation Test: 100 forks
XElapsed Time: 1.98 seconds (variance 0.162)
XCPU Time: 1.63 seconds [ 0.00u + 1.63s ] (variance 0.003)
X
XExecl Throughput Test: 100 execs
XElapsed Time: 5.80 seconds (variance 0.716)
XCPU Time: 3.02 seconds [ 0.10u + 2.92s ] (variance 0.010)
X
XC Compiler Test:
X
Xcc -c cctest.c
XElapsed Time: 5.50 seconds (variance 0.130)
XCPU Time: 3.83 seconds [ 2.87u + 0.97s ] (variance 0.013)
X
Xcc cctest.o
XElapsed Time: 3.27 seconds (variance 0.103)
XCPU Time: 0.77 seconds [ 0.30u + 0.47s ] (variance 0.003)
X
XSequential Memory Access Test: 100000 Accesses
X
XArray Size: 8 Kbytes
XElapsed Time: 0.20 seconds (variance 0.005)
XCPU Time: 0.21 seconds (variance 0.001)
XReal Rate: 508475 int array accesses / second
X
XArray Size: 64 Kbytes
XElapsed Time: 0.44 seconds (variance 0.113)
XCPU Time: 0.26 seconds (variance 0.001)
XReal Rate: 227273 int array accesses / second
X
XArray Size: 512 Kbytes
XElapsed Time: 0.38 seconds (variance 0.001)
XCPU Time: 0.38 seconds (variance 0.001)
XReal Rate: 262009 int array accesses / second
X
XRandom Memory Access Test: 100000 Accesses
X
XArray Size: 8 Kbytes
XElapsed Time: 0.16 seconds (variance 0.000)
XCPU Time: 0.17 seconds (variance 0.000)
XReal Rate: 631579 int array accesses / second
X
XArray Size: 64 Kbytes
XElapsed Time: 0.33 seconds (variance 0.000)
XCPU Time: 0.33 seconds (variance 0.000)
XReal Rate: 301508 int array accesses / second
X
XArray Size: 512 Kbytes
XElapsed Time: 0.57 seconds (variance 0.004)
XCPU Time: 0.55 seconds (variance 0.001)
XReal Rate: 175953 int array accesses / second
X
XFilesystem Throughput Test:
X
XFile Size: 62 blocks
XWrite: 86.7 Kbytes per second (variance 1049.1)
XRead: 78.4 Kbytes per second (variance 421.1)
XCopy: 38.1 Kbytes per second (variance 34.4)
X
XFile Size: 125 blocks
XWrite: 116.2 Kbytes per second (variance 3099.1)
XRead: 82.6 Kbytes per second (variance 2.8)
XCopy: 42.2 Kbytes per second (variance 19.6)
X
XFile Size: 250 blocks
XWrite: 193.0 Kbytes per second (variance 1404.6)
XRead: 91.8 Kbytes per second (variance 14.9)
XCopy: 46.1 Kbytes per second (variance 5.4)
X
XFile Size: 500 blocks
XWrite: 99.0 Kbytes per second (variance 89.5)
XRead: 97.5 Kbytes per second (variance 20.6)
XCopy: 47.3 Kbytes per second (variance 1.6)
X
XOutput sent to ... /dev/ttyp0
XDirectories for temporary files ... Tmp
X
XFilesystem total kbytes kbytes percent
X node kbytes used free used Mounted on
X/dev/ra0a 7447 4721 1981 70% /
X/dev/ra0g 42003 30222 7580 80% /usr
X
XSIGALRM check: 12 x 5 sec delays takes 60.05 wallclock secs (error -0.08%)
XSimulated Multi-user Work Load Test:
X
X1 Concurrent Users, each with Input Keyboard Rate 2 chars / sec
XElapsed Time: 355.97 seconds (variance 0.953)
XCPU Time: 22.20 seconds [ 15.23u + 6.97s ] (variance 0.010)
X
X4 Concurrent Users, each with Input Keyboard Rate 2 chars / sec
XElapsed Time: 359.60 seconds (variance 6.688)
XCPU Time: 88.80 seconds [ 61.20u + 27.60s ] (variance 0.026)
X
X8 Concurrent Users, each with Input Keyboard Rate 2 chars / sec
XElapsed Time: 380.70 seconds (variance 90.094)
XCPU Time: 178.37 seconds [ 123.30u + 55.07s ] (variance 0.652)
X
X 1 interactive users.
XEnd Benchmark Run (Wed Jun 24 09:33:55 EDT 1987) ....
End-of-File-Grunt
if test 5474 -ne `cat 'log.uVaxII' | wc -c`
then
echo 'shar: transmission error (expected 5474 characters)'
fi
echo 'x - makework.c'
if test -f 'makework.c'
then
echo 'shar: over-writing existing file makework.c'
fi
sed 's/^X//' > makework.c <<'End-of-File-Grunt'
X/*
X * makework -- emulate a series of terminal users
X *
X * makework nusers
X *
X * job streams are specified on standard input with lines of the form
X * home_dir cmd_path_name [ options ] [ <stdin_file ] [ >stdout_file ]
X *
X * Input is send to all nuser instances of the commands in the
X * job streams at a rate not in excess of "rate" characters per second
X * per command
X *
X * environment variables $rate and $tty control typing rate (characters
X * per second) and destination of echoed output.
X *
X * $Header: makework.c,v 3.9 87/09/17 05:55:13 kenj Exp $
X */
X
X#include "makework.h"
X
X#define DEF_RATE 5.0
X#define GRANULE 5
X#define CHUNK 60
X
Xfloat thres;
Xfloat est_rate = DEF_RATE;
Xint firstuser; /* ordinal identification of first user for this
X * process */
Xint exit_status = 0;
Xint sigpipe; /* pipe write error flag */
Xint nstream;
X
Xstatic stream *cp;
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int i;
X int l;
X int fcopy = 0; /* fd for copy output */
X int master = 1; /* the REAL master, == 0 for clones */
X int cmseq = 0; /* clone/master seq number */
X int done; /* count of children finished */
X int output; /* aggregate output char count for all
X children */
X int c;
X int nch; /* # characters to write */
X int written; /* # characters actully written */
X char logname[20]; /* name of the log file(s) */
X int nusers;
X int onalarm();
X int pipeerr();
X int wrapup();
X int grunt();
X int pvec[2]; /* for pipes */
X char *p;
X char *prog; /* my name */
X char *getenv();
X
X#ifndef DEBUG
X freopen("Tmp/masterlog.00", "a", stderr);
X#endif
X fprintf(stderr, "*** New Run *** ");
X prog = argv[0];
X if ((p = getenv("rate")) != (char *)0) {
X sscanf(p, "%f", &est_rate);
X if (est_rate <= 0) {
X fprintf(stderr, "%s: bad rate, reset to %.2f chars/sec\n", prog, DEF_RATE);
X est_rate = DEF_RATE;
X }
X#ifdef DEBUG
X else
X fprintf(stderr, "%s: typing rate reset to %.2f chars/sec\n", prog, est_rate);
X#endif
X }
X if ((p = getenv("tty")) != (char *)0) {
X fcopy = open(p, 1);
X if (fcopy < 0)
X fcopy = creat(p, 0600);
X if (fcopy < 0) {
X fprintf(stderr, "%s: cannot open copy file '%s'\n", prog, p);
X fflush(stderr);
X exit(2);
X }
X lseek(fcopy, 0L, 2); /* append at end of file */
X }
X
X if (argc < 2) {
X fprintf(stderr, "%s: missing nusers\n", prog);
X fflush(stderr);
X exit(4);
X }
X
X nusers = atoi(argv[1]);
X if (nusers < 1) {
X fprintf(stderr, "%s: impossible nusers (%d<-%s)\n", prog, nusers, argv[1]);
X fflush(stderr);
X exit(4);
X }
X fprintf(stderr, "%d Users\n", nusers);
X argc--;
X argv++;
X
X /* clone copies of myself to run up to MAXSTREAM jobs each */
X firstuser = MAXSTREAM;
X fprintf(stderr, "master pid %d\n", getpid());
X fflush(stderr);
X while (nusers > MAXSTREAM) {
X fflush(stderr);
X if (nusers >= 2*MAXSTREAM)
X /* the next clone must run MAXSTREAM jobs */
X nstream = MAXSTREAM;
X else
X /* the next clone must run the leftover jobs */
X nstream = nusers - MAXSTREAM;
X /* build job streams for the clone */
X getwork(nstream);
X#ifdef DEBUG
X dumpwork();
X#endif
X cmseq = firstuser/MAXSTREAM;
X if ((l = fork()) == -1) {
X /* fork failed */
X fatal("** clone fork failed **\n");
X goto bepatient;
X } else if (l > 0) {
X fprintf(stderr, "clone %d pid %d\n", cmseq, l);
X /* I am the master with nstream fewer jobs to run */
X nusers -= nstream;
X firstuser += MAXSTREAM;
X continue;
X } else {
X /* I am a clone, run MAXSTREAM jobs */
X master = 0;
X nusers = nstream;
X#ifndef DEBUG
X sprintf(logname, "Tmp/masterlog.%02d", cmseq);
X freopen(logname, "w", stderr);
X#endif
X break;
X }
X }
X if (master) {
X firstuser = 0;
X cmseq = 0;
X nstream = nusers;
X /* build job streams for the master */
X getwork(nstream);
X#ifdef DEBUG
X dumpwork();
X#endif
X }
X
X close(0);
X
X for (i = 0; i < nstream; i++ ) {
X if (master)
X fprintf(stderr, "user %d master stream %d ", firstuser+i, i);
X else
X fprintf(stderr, "user %d clone %d stream %d ", firstuser+i, cmseq, i);
X if (pipe(pvec) == -1) {
X /* this is fatal */
X fatal("** pipe failed **\n");
X goto bepatient;
X }
X fflush(stderr);
X if ((work[i].pid = fork()) == 0) {
X int fd;
X /* the command */
X if (pvec[0] != 0) {
X close(0);
X dup(pvec[0]);
X }
X#ifndef DEBUG
X sprintf(logname, "Tmp/userlog.%02d", firstuser+i);
X freopen(logname, "w", stderr);
X#endif
X for (fd = 3; fd < 24; fd++)
X close(fd);
X if (work[i].tty[0] != '\0') {
X /* redirect std output */
X if (freopen(work[i].tty, "w", stdout) == NULL) {
X fprintf(stderr, "makework: cannot open %s for std output\n",
X work[i].tty);
X fflush(stderr);
X goto bepatient;
X }
X }
X if (chdir(work[i].home) == -1) {
X fprintf(stderr, "makework: chdir to \"%s\" failed!\n",
X work[i].home);
X fflush(stderr);
X goto bepatient;
X }
X sprintf(logname, "USER.%02d", firstuser+i);
X if (close(creat(logname, 0600)) == -1) {
X fprintf(stderr, "makework: creat \"%s\" failed!\n", logname);
X fflush(stderr);
X goto bepatient;
X }
X
X execv(work[i].cmd, work[i].av);
X /* don't expect to get here! */
X fatal("** exec failed **\n");
X goto bepatient;
X }
X else if (work[i].pid == -1) {
X fatal("** fork failed **\n");
X goto bepatient;
X }
X else {
X close(pvec[0]);
X work[i].fd = pvec[1];
X work[i].line = work[i].bp = work[i].buf;
X fprintf(stderr, "pid %d pipe fd %d", work[i].pid, work[i].fd);
X if (work[i].tty[0] != '\0')
X fprintf(stderr, " > %s", work[i].tty);
X fputc('\n', stderr);
X }
X }
X fflush(stderr);
X
X srand(time(0));
X thres = 0;
X done = output = 0;
X for (i = 0; i < nstream; i++) {
X if (work[i].blen == 0)
X done++;
X else
X thres += est_rate * GRANULE;
X }
X est_rate = thres;
X
X signal(SIGALRM, onalarm);
X signal(SIGPIPE, pipeerr);
X alarm(GRANULE);
X while (done < nstream) {
X for (i = 0; i < nstream; i++) {
X cp = &work[i];
X if (cp->xmit >= cp->blen) continue;
X l = rand() % CHUNK + 1; /* 1-CHUNK chars */
X if (l == 0) continue;
X if (cp->xmit + l > cp->blen)
X l = cp->blen - cp->xmit;
X p = cp->bp;
X cp->bp += l;
X cp->xmit += l;
X#ifdef DEBUG
X fprintf(stderr, "child %d, %d processed, %d to go\n", i, cp->xmit, cp->blen - cp->xmit);
X#endif
X while (p < cp->bp) {
X if (*p == '\n' || (p == &cp->bp[-1] && cp->xmit >= cp->blen)) {
X /* write it out */
X nch = p - cp->line + 1;
X if ((written = write(cp->fd, cp->line, nch)) != nch) {
X /* argh! */
X cp->line[nch] = '\0';
X fprintf(stderr, "user %d cmd %s ",
X firstuser+i, cp->line);
X fprintf(stderr, "write(,,%d) returns %d\n", nch, written);
X if (sigpipe)
X fatal("** SIGPIPE error **\n");
X else
X fatal("** write error **\n");
X goto bepatient;
X
X }
X if (fcopy)
X write(fcopy, cp->line, p - cp->line + 1);
X#ifdef DEBUG
X fprintf(stderr, "child %d gets \"", i);
X {
X char *q = cp->line;
X while (q <= p) {
X if (*q >= ' ' && *q <= '~')
X fputc(*q, stderr);
X else
X fprintf(stderr, "\\%03o", *q);
X q++;
X }
X }
X fputc('"', stderr);
X#endif
X cp->line = &p[1];
X }
X p++;
X }
X if (cp->xmit >= cp->blen) {
X done++;
X close(cp->fd);
X#ifdef DEBUG
X fprintf(stderr, "child %d, close std input\n", i);
X#endif
X }
X output += l;
X }
X while (output > thres) {
X pause();
X#ifdef DEBUG
X fprintf(stderr, "after pause: output, thres, done %d %.2f %d\n", output, thres, done);
X#endif
X }
X }
X
Xbepatient:
X alarm(0);
X/****
X * If everything is going OK, we should simply be able to keep
X * looping unitil 'wait' fails, however some descendent process may
X * be in a state from which it can never exit, and so a timeout
X * is used.
X * 5 minutes should be ample, since the time to run all jobs is of
X * the order of 5-10 minutes, however some machines are painfully slow,
X * so the timeout has been set at 20 minutes (1200 seconds).
X ****/
X signal(SIGALRM, grunt);
X alarm(1200);
X while ((c = wait(&l)) != -1) {
X for (i = 0; i < nstream; i++) {
X if (c == work[i].pid) {
X fprintf(stderr, "user %d pid %d done", firstuser+i, c);
X if (l != 0) {
X if (l & 0x7f)
X fprintf(stderr, " status %d", l & 0x7f);
X if (l & 0xff00)
X fprintf(stderr, " exit code %d", (l>>8) & 0xff);
X exit_status = 4;
X }
X fputc('\n', stderr);
X c = work[i].pid = -1;
X break;
X }
X }
X if (c != -1) {
X fprintf(stderr, "clone %d done, pid %d ", cmseq, c);
X if (l != 0) {
X if (l & 0x7f)
X fprintf(stderr, " status %d", l & 0x7f);
X if (l & 0xff00)
X fprintf(stderr, " exit code %d", (l>>8) & 0xff);
X exit_status = 4;
X }
X fputc('\n', stderr);
X }
X }
X alarm(0);
X wrapup("Finished waiting ...");
X
X
X}
X
Xonalarm()
X{
X thres += est_rate;
X signal(SIGALRM, onalarm);
X alarm(GRANULE);
X}
X
Xgrunt()
X{
X /* timeout after label "bepatient" in main */
X exit_status = 4;
X wrapup("Timed out waiting for jobs to finish ...");
X}
X
Xpipeerr()
X{
X sigpipe++;
X}
X
Xwrapup(reason)
Xchar *reason;
X{
X int i;
X int killed = 0;
X fflush(stderr);
X for (i = 0; i < nstream; i++) {
X if (work[i].pid > 0 && kill(work[i].pid, SIGKILL) != -1) {
X if (!killed) {
X killed++;
X fprintf(stderr, "%s\n", reason);
X fflush(stderr);
X }
X fprintf(stderr, "user %d pid %d killed off\n", firstuser+i, work[i].pid);
X fflush(stderr);
X }
X }
X exit(exit_status);
X}
End-of-File-Grunt
if test 9455 -ne `cat 'makework.c' | wc -c`
then
echo 'shar: transmission error (expected 9455 characters)'
fi
echo 'x - makework.h'
if test -f 'makework.h'
then
echo 'shar: over-writing existing file makework.h'
fi
sed 's/^X//' > makework.h <<'End-of-File-Grunt'
X#include <stdio.h>
X#include <signal.h>
X/* $Header: makework.h,v 1.4 87/06/24 08:33:56 kjmcdonell Beta $ */
X
X#define MAXSTREAM 12
X
Xtypedef struct st_stream {
X char *home; /* home dir for job stream */
X char *cmd; /* name of command to run */
X char **av; /* arguments to command */
X char *buf; /* standard input buffer */
X int blen; /* size of standard input buffer */
X int xmit; /* # characters sent */
X char *bp; /* std input buffer pointer */
X char *tty; /* standard output (filename) */
X int fd; /* stdin to command */
X int pid; /* PID of stream command */
X char *line; /* start of input line */
X} stream;
X
Xextern stream work[];
X
Xextern int nstream; /* number of concurrent streams to be
X * simulated by this process */
Xextern int exit_status; /* returned to parent */
End-of-File-Grunt
if test 787 -ne `cat 'makework.h' | wc -c`
then
echo 'shar: transmission error (expected 787 characters)'
fi
echo 'x - mem.awk'
if test -f 'mem.awk'
then
echo 'shar: over-writing existing file mem.awk'
fi
sed 's/^X//' > mem.awk <<'End-of-File-Grunt'
X# $Header: mem.awk,v 3.4 87/06/22 14:27:39 kjmcdonell Beta $
X/real/ { next }
X/^[0-9][ .0-9-]*$/ && NF==3 { \
X r=$2/1000; \
X if (r < 0) { \
X print "** Iteration ",iter+1," real loop < ohead: ",$0; \
X r=0; \
X } \
X iter++; numacc=$1; real+=r; r2+=r*r; cpu+=$3; c2+=$3*$3; \
X next; \
X }
X{ print "** Iteration ",iter+1," Failed: ",$0 }
XEND {\
X if (iter > 0) { \
X printf "Elapsed Time: %.2f seconds",real/iter; \
X if (iter > 1) printf " (variance %.3f)",(r2-2*real*real/iter+real*real/iter)/(iter-1); \
X printf "\nCPU Time: %.2f seconds",cpu/iter; \
X if (iter > 1) printf " (variance %.3f)",(c2-2*cpu*cpu/iter+cpu*cpu/iter)/(iter-1); \
X print; \
X printf "Real Rate: %.0f int array accesses / second\n",(numacc*iter)/real; \
X } else { \
X print "Elapsed Time: -- no measured results!!"; \
X print "CPU Time: -- no measured results!!"; \
X } \
X }
End-of-File-Grunt
if test 882 -ne `cat 'mem.awk' | wc -c`
then
echo 'shar: transmission error (expected 882 characte% for