sources-request@munnari.oz (09/17/87)
Submitted by: kenj@moncsbruce.oz.au (Ken McDonell) Posting-number: Volume 11, Issue 32 Archive-name: musbus/Part04 #! /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: # mem.c # mk1 # mk2 # mkcomp # mkdistrib # mkinstall # mkperm.c # mkprofile # mkscript # mkscript.out # mktbl # musbus.1 # pipe.c # precision.c # run # script.master # spawn.c # syscall.c # tbl.1 # tbl.2 # tbl.3 # tbl.4 # tbl.5 # time.awk # ttychk.c # util.c # This archive created: Thu Sep 17 06:49:08 EST 1987 export PATH; PATH=/bin:$PATH echo 'x - mem.c' if test -f 'mem.c' then echo 'shar: over-writing existing file mem.c' fi sed 's/^X//' > mem.c <<'End-of-File-Grunt' X/* X * mem [ -ssize ] [ -niter ] X * X * perform int array accesses X * array size (if given) is in Kbytes, default is 8K X * iter accesses of each type, default is iter=100000 X * Configuration options X * #ifdef random random access X * #ifndef random sequential access X * #ifdef awk output on stderr for benchmark script X * #ifdef debug output on stdout for diagnostics X * X * #ifdef BSD4v1 4.1 BSD, ftime() exists X * #ifdef BSD4v2 4.2 BSD, gettimeofday() exists X * #ifdef SysV System V, times() returns real time X * X * $Header: mem.c,v 3.5 87/08/06 08:11:10 kenj Exp $ X */ X X#include <sys/types.h> X#include <sys/times.h> X#ifdef BSD4v1 X#include <sys/timeb.h> X#endif X#ifdef BSD4v2 X#include <sys/time.h> X#include <sys/resource.h> X#endif X#include <stdio.h> X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int *tab; X register char *p; X register int i; X register int j; X register int mask; X register int k; X long iter = 100000; X int size = 8*1024 / sizeof(int); X struct tms tbuffer; X long access[2]; X long ohead[2]; X#ifdef BSD4v1 X struct timeb tbuf; X int msec; X#endif X#ifdef BSD4v2 X struct timeval tbuf; X struct timezone tzone; X struct rusage rubuf; X long rusec, cpusec; X#endif X char *prog = argv[0]; X char *malloc(); X#ifdef random X long index[1000]; X#endif X X while (argc-- > 1) { X switch (argv[1][1]) { X case 's': X size = atoi(&argv[1][2])*1024 / sizeof(int); X break; X case 'n': X iter = atoi(&argv[1][2]); X break; X default: X printf("Usage: %s [-ssize] [-niter]\n", prog); X exit(1); X } X argv++; X } X X mask = size / sizeof(int); X X if ((tab = (int *)malloc(size*sizeof(int))) == (int *)0) { X printf("%s: malloc failed for %d bytes\n", prog, size*sizeof(int)); X exit(1); X } X X#ifdef random X /* build random array index map */ X for (i = 0; i < 1000; i++) X index[i] = rand() % mask; X#endif X X /* measure overhead for loop */ X srand(1); X#ifdef SysV X ohead[0] = -times(&tbuffer); X ohead[1] = -tbuffer.tms_utime - tbuffer.tms_stime; X#else X#ifdef BSD4v1 X times(&tbuffer); X ftime(&tbuf); X ohead[0] = -tbuf.time; X msec = tbuf.millitm; X ohead[1] = -tbuffer.tms_utime - tbuffer.tms_stime; X#else X#ifdef BSD4v2 X gettimeofday(&tbuf, &tzone); X getrusage(RUSAGE_SELF, &rubuf); X#ifdef debug X printf("real %d+%d user %d+%d sys %d+%d\n", tbuf.tv_sec, tbuf.tv_usec, X rubuf.ru_utime.tv_sec, rubuf.ru_utime.tv_usec, X rubuf.ru_stime.tv_sec, rubuf.ru_stime.tv_usec); X#endif X ohead[0] = -tbuf.tv_sec; X rusec = tbuf.tv_usec; X ohead[1] = -rubuf.ru_utime.tv_sec - rubuf.ru_stime.tv_sec; X cpusec = rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec; X#else X What sort of Unix system if this? X#endif X#endif X#endif X for (i = 0, k = 0; i < iter; i++) { X#ifdef random X j = index[k]; X k++; X if (k >= 1000) k = 0; X#else X j = i % mask; X#endif X } X#ifdef SysV X ohead[0] += times(&tbuffer); X ohead[1] += tbuffer.tms_utime + tbuffer.tms_stime; X#else X#ifdef BSD4v1 X times(&tbuffer); X ftime(&tbuf); X ohead[0] += tbuf.time; X ohead[0] = ohead[0]*1000 + tbuf.millitm - msec; X ohead[1] += tbuffer.tms_utime + tbuffer.tms_stime; X#else X#ifdef BSD4v2 X gettimeofday(&tbuf, &tzone); X getrusage(RUSAGE_SELF, &rubuf); X#ifdef debug X printf("real %d+%d user %d+%d sys %d+%d\n", tbuf.tv_sec, tbuf.tv_usec, X rubuf.ru_utime.tv_sec, rubuf.ru_utime.tv_usec, X rubuf.ru_stime.tv_sec, rubuf.ru_stime.tv_usec); X#endif X ohead[0] += tbuf.tv_sec; X ohead[0] = ohead[0]*1000 + (tbuf.tv_usec - rusec)/1000; X ohead[1] += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec; X ohead[1] = ohead[1]*60 + 60*(rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec - cpusec)/1000000; X#endif X#endif X#endif X#ifdef debug X printf("overhead real: %d msec cpu: %.1f sec\n", ohead[0], ((float)ohead[1])/60.); X#endif X X /* perform accesses */ X srand(1); X#ifdef SysV X access[0] = -times(&tbuffer); X access[1] = -tbuffer.tms_utime - tbuffer.tms_stime; X#else X#ifdef BSD4v1 X times(&tbuffer); X ftime(&tbuf); X access[0] = -tbuf.time; X msec = tbuf.millitm; X access[1] = -tbuffer.tms_utime - tbuffer.tms_stime; X#else X#ifdef BSD4v2 X gettimeofday(&tbuf, &tzone); X getrusage(RUSAGE_SELF, &rubuf); X#ifdef debug X printf("real %d+%d user %d+%d sys %d+%d\n", tbuf.tv_sec, tbuf.tv_usec, X rubuf.ru_utime.tv_sec, rubuf.ru_utime.tv_usec, X rubuf.ru_stime.tv_sec, rubuf.ru_stime.tv_usec); X#endif X access[0] = -tbuf.tv_sec; X rusec = tbuf.tv_usec; X access[1] = -rubuf.ru_utime.tv_sec - rubuf.ru_stime.tv_sec; X cpusec = rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec; X#endif X#endif X#endif X for (i = 0, k = 0; i < iter; i++) { X#ifdef random X j = tab[index[k]]; X k++; X if (k >= 1000) k = 0; X#else X j = tab[i % mask]; X#endif X } X#ifdef SysV X access[0] += times(&tbuffer); X access[1] += tbuffer.tms_utime + tbuffer.tms_stime; X#else X#ifdef BSD4v1 X times(&tbuffer); X ftime(&tbuf); X access[0] += tbuf.time; X access[0] = access[0]*1000 + tbuf.millitm - msec; X access[1] += tbuffer.tms_utime + tbuffer.tms_stime; X#else X#ifdef BSD4v2 X gettimeofday(&tbuf, &tzone); X getrusage(RUSAGE_SELF, &rubuf); X#ifdef debug X printf("real %d+%d user %d+%d sys %d+%d\n", tbuf.tv_sec, tbuf.tv_usec, X rubuf.ru_utime.tv_sec, rubuf.ru_utime.tv_usec, X rubuf.ru_stime.tv_sec, rubuf.ru_stime.tv_usec); X#endif X access[0] += tbuf.tv_sec; X access[0] = access[0]*1000 + (tbuf.tv_usec - rusec)/1000; X access[1] += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec; X access[1] = access[1]*60 + 60*(rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec - cpusec)/1000000; X#endif X#endif X#endif X#ifdef awk X fprintf(stderr, "%d %d %.3f\n", iter, access[0] - ohead[0], X ((float)(access[1] - ohead[1]))/60.); X#endif X#ifdef debug X printf("total real: %d msec cpu: %.1f sec\n", access[0], ((float)access[1])/60.); X printf("access real: %d msec cpu: %.1f sec\n", access[0] - ohead[0], X ((float)(access[1] - ohead[1]))/60.); X printf("%d Kbyte array: %.1f accesses per second\n", size*sizeof(int)/1024, X iter*1000.0/((float)(access[0] - ohead[0]))); X#endif X X exit(0); X} End-of-File-Grunt if test 6343 -ne `cat 'mem.c' | wc -c` then echo 'shar: transmission error (expected 6343 characters)' fi echo 'x - mk1' if test -f 'mk1' then echo 'shar: over-writing existing file mk1' fi sed 's/^X//' > mk1 <<'End-of-File-Grunt' X#! /bin/sh X# Common premable for mktbl and mkcomp X# $Header: mk1,v 1.3 87/06/24 13:40:55 kjmcdonell Beta $ Xif test ! -f log.$2 Xthen X if test ! -f ../Results/log.$2 X then X echo "$1: cannot open MUSBUS log file \"log.$2\"" X exit 1 X else X log=../Results/log.$2 X fi X else X log=log.$2 Xfi Xif grep '^MC=' $log >/dev/null Xthen X : Xelse X ./Config $log >/dev/tty Xfi Xif grep 'arithoh' $log >/dev/null Xthen X if grep '(Actual' $log >/dev/null X then X : X else X ./Adjust $log X fi Xfi Xecho "log=$log" Xawk ' X/^[A-Z][A-Z]*=/ { print; next } X/^Start Benchmark Run \(... / { print "V=\"3.0\"" X print "D=\"",$6,$5,$9,"\"" X exit } X/^Start Benchmark \(Version/ { print "V=\"",$4,"\"" X print "D=\"",$8,$7,$11,"\"" X exit } X/^Start Benchmark Run \(MUSBUS/ { print "V=\"",$6,"\"" X nextdate=1 X next } Xnextdate==1 { print "D=\"",$3,$2,$6,"\"" X exit } X' $log \ X| sed \ X -e 's/\(V="[^"]*\))/\1/g' \ X -e 's/,//g' \ X -e 's/" */"/g' \ X -e 's/ *"/"/g' Xexit 0 End-of-File-Grunt if test 980 -ne `cat 'mk1' | wc -c` then echo 'shar: transmission error (expected 980 characters)' fi echo 'x - mk2' if test -f 'mk2' then echo 'shar: over-writing existing file mk2' fi sed 's/^X//' > mk2 <<'End-of-File-Grunt' X#! /bin/sh X# extract goodies from the log file X# $Header: mk2,v 1.3 87/08/07 15:40:36 kenj Exp $ Xawk ' X/^$/ { next } X/^[A-Z][A-Z]*=/ { next } X/Benchmark/ { next } X/Disk Problem/ { next } X/C Compiler Test/ { next } X/iterations/ { next } X/interactive users/ { next } X/loop < ohead:/ { next } X/Synthetic Work/ { mem=0; next } X/Simulated Work/ { mem=0; next } X/Simulated Multi-user/ { mem=0; next } X/type = arithoh/ { tbl=1; t="Loop Overhead"; next } X/type = register/ { tbl=1; t="Register Arithmetic"; next } X/type = short/ { tbl=1; t="Short Arithmetic"; next } X/type = int/ { tbl=1; t="Integer Arithmetic"; next } X/type = long/ { tbl=1; t="Long Arithmetic"; next } X/type = float/ { tbl=1; t="Float Arithmetic"; next } X/type = double/ { tbl=1; t="Double Arithmetic"; next } X/sqrt/ { tbl=1; t="dc sqrt(2)"; und=1; next } X/Hanoi/ { tbl=1; t="Recursion"; next } X/System Call/ { tbl=1; t="System Calls"; und=1; next } X/Pipe Throughput/ { tbl=1; t="Pipe Throughput"; next } X/Pipe-based Context/ { tbl=1; t="Pipes & Context Switching"; next } X/Signal-based Context/ { tbl=1; t="Signals & Context Switching"; next } X/Process Creation/ { tbl=1; t="Process Create"; next } X/Execl/ { tbl=1; t="Execing"; next } X/cc -c.* cctest.c/ { tbl=1; t="C Compile"; und=1; next } X/cc -c.* fstime.c/ { tbl=1; t="C Compile"; und=1; next } X/cc cctest.o/ { tbl=1; t="C Load"; next } X/cc fstime.o/ { tbl=1; t="C Load"; next } X/^[0-9]+ Concurrent/ { tbl=5; t=$1 "_Users"; next} X/Elapsed/ && /Actual/ { e=$(NF-1); next } X/Elapsed/ { e=$3; next } X/CPU/ && /Actual/ { c=$(NF-1) X if (intbl != tbl) { X if (intbl) print ".TE\n.)b" X printf ".so tbl.%d\n",tbl X intbl=tbl X } X if (und) { print "_"; und=0 } X printf "%s\t%.2f\t%.2f\n",t,e,c X t="" X next X } X/CPU/ && mem==0 { c=$3 X if (intbl != tbl) { X if (intbl) print ".TE\n.)b" X printf ".so tbl.%d\n",tbl X intbl=tbl X } X if (und) { print "_"; und=0 } X printf "%s\t%.2f\t%.2f\n",t,e,c X t="" X next X } X/CPU/ && mem!=0 { next } X/Sequential Memory/ { mem=1; found++; X if (intbl != 2) { X if (intbl) print ".TE\n.)b" X print ".so tbl.2" X intbl=2 X } X next X } X/Random Memory/ { mem=2; found++; tbl=2 X if (intbl != 2) { X if (intbl) print ".TE\n.)b" X printf ".so tbl.2" X intbl=2 X } X next X } X/Array Size/ { size=$3; next } X/Real Rate/ { if (mem==1) s[size]=$3/1000 X if (mem==2) r[size]=$3/1000 X if (found==2) { X printf "%d\t%.2f\t%.2f\n",size,s[size],r[size] X if (size==512) { X mem=0 X found=0 X } X } X next X } X/Filesystem Throughput/ { if (intbl) print ".TE\n.)b" X print ".so tbl.3" X print ".so disks" X print ".so tbl.4" X intbl=4 X next } X/File Size/ { printf "%sK bytes",$3; next } X/Write:/ { printf "\t%.2f",$2; next } X/Read:/ { printf "\t%.2f",$2; next } X/Copy:/ { printf "\t%.2f",$2; print ""; next } X/\/dev/ || /tty/ || /used/ || /[dD]irector/ || /wallclock/ { next } X/^[^ ][^ ]*:\/[^ ]/ { next } # df for NFS mounted filesystem X { print $0 } XEND { if (intbl) print ".TE\n.)b" } X' $1 End-of-File-Grunt if test 3138 -ne `cat 'mk2' | wc -c` then echo 'shar: transmission error (expected 3138 characters)' fi echo 'x - mkcomp' if test -f 'mkcomp' then echo 'shar: over-writing existing file mkcomp' fi sed 's/^X//' > mkcomp <<'End-of-File-Grunt' X#! /bin/sh X# $Header: mkcomp,v 1.3 87/09/17 06:08:30 kenj Exp $ X# Make tbl source for pairwise machine comparison. Xprog=$0 Xif test $# -ne 2 Xthen X echo "Usage: $prog machine compared-to" X exit 1 Xfi Xout=$1-$2 Xfor x in 1 2 Xdo X init=`./mk1 $prog $1` X test $? != 0 && echo "$init" && exit 1 X test $x = 1 && shift X init=`echo $init | sed "s/=/$x=/g"` X eval $init Xdone Xcat >$out <<End-of-File-Grunt X.\" \$Compile: typeset -me -t %f X.nr tf 0 X.nr tp 10 X.nr pp 10 X.nr fp 10 X.ll 6.5i X.sz 10 X.he 'MUSBUS'Monash UNIX Benchmarking Suite'' X.fo '$MC1 \- $MC2''\*(td' X.(b X.TS Xdoublebox,center; Xl | c | c Xl | l | l. X This System Relative To X_ XProcessor $MC1 $MC2 X $OPT1 $OPT2 XMemory $MEM1 $MEM2 XUNIX Version $UNIX1 $UNIX2 XTest Date $D1 $D2 XMUSBUS Version $V1 $V2 X.TE X.)b XEnd-of-File-Grunt X X./mk2 $log2 \ X| sed \ X -e '/^_$/d' \ X -e '/^\.so /d' \ X -e '/^\.TE/d' \ X -e '/^\.)b/d' \ X -e 's/^\([^ ]* \)\(.*\)/\/^\1\/s\/$\/ \2\//' \ X > tmp.$$ X Xecho "Disks $DISKS1 $DISKS2" > disks X./mk2 $log1 \ X| sed -f tmp.$$ \ X| awk ' XBEGIN { FS=" " } X/tbl.1/ { inv = 0 } X/tbl.2/ { inv = 1 } X/tbl.3/ { inv = 1 } X/tbl.5/ { inv = 0 } X/[0-9]\.[0-9]/ && NF==5 { X printf $1; X r2 = r1 = "\\*(if" X if (!inv) { X if ($2) r1 = $4/$2 X if ($3) r2 = $5/$3 X } X else { X if ($4) r1 = $2/$4 X if ($5) r2 = $3/$5 X } X printf "\t%.2f\t%.2f\t%.2f\t%.2f\n",$2,$3,r1,r2 X next X} X/[0-9]\.[0-9]/ && NF==7 { X printf $1; X if (!inv) { X if ($2) r1 = $5/$2 X if ($3) r2 = $6/$3 X if ($4) r3 = $7/$4 X } X else { X if ($5) r1 = $2/$5 X if ($6) r2 = $3/$6 X if ($7) r3 = $4/$7 X } X printf "\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n",$2,$3,$4,r1,r2,r3 X next; X} X/[0-9]\.[0-9]/ { printf "%s\t?\t?\t?\t?\n",$1; next } X{ print }' \ X| sed \ X -e 's/^\.so tbl\./.so comptbl./' \ X -e 's/^\([1-9][0-9]*\)_Users/\1/' \ X| soelim >>$out Xrm -f disks tmp.$$ End-of-File-Grunt if test 1792 -ne `cat 'mkcomp' | wc -c` then echo 'shar: transmission error (expected 1792 characters)' fi echo 'x - mkdistrib' if test -f 'mkdistrib' then echo 'shar: over-writing existing file mkdistrib' fi sed 's/^X//' > mkdistrib <<'End-of-File-Grunt' X#! /bin/sh X# Package things up ready for a distribution X# $Header: mkdistrib,v 1.4 87/09/10 05:09:28 kenj Exp $ X Xmake purge X Xfor dir in * Xdo X test -d $dir -a $dir != "RCS" || continue X cd $dir X if test "`echo *`" != '*' X then X if test -f Makefile X then X make clean X fi X for file in * X do X test -f "../$file" || continue X ver=1 X while test -f ../$file,$ver X do X ver=`expr $ver + 1` X done X mv $file $file,$ver X done X ls * >../$dir.files X mv * .. X fi X cd .. X rmdir $dir Xdone X Xrm -rf Tmp End-of-File-Grunt if test 509 -ne `cat 'mkdistrib' | wc -c` then echo 'shar: transmission error (expected 509 characters)' fi echo 'x - mkinstall' if test -f 'mkinstall' then echo 'shar: over-writing existing file mkinstall' fi sed 's/^X//' > mkinstall <<'End-of-File-Grunt' X#! /bin/sh X# Undo the flattening done by mkdistrib. X# $Header: mkinstall,v 1.3 87/09/10 05:08:45 kenj Exp $ Xfor list in *.files Xdo X if test "$list" = '*.files' X then X continue X fi X dir=`echo $list | sed 's/.files//'` X test -d $dir || mkdir $dir X mv `cat $list` $dir X cd $dir X for file in * X do X case $file X in X *,[0-9]) X mv $file `echo $file | sed 's/,[0-9]$//'` X ;; X esac X done X cd .. X rm -f $list Xdone X Xtest -d Tmp || mkdir Tmp End-of-File-Grunt if test 471 -ne `cat 'mkinstall' | wc -c` then echo 'shar: transmission error (expected 471 characters)' fi echo 'x - mkperm.c' if test -f 'mkperm.c' then echo 'shar: over-writing existing file mkperm.c' fi sed 's/^X//' > mkperm.c <<'End-of-File-Grunt' X#include <stdio.h> X#ifndef lint Xstatic char RCSid[] = "$Header: mkperm.c,v 1.2 87/06/22 14:32:26 kjmcdonell Beta $"; X#endif X X/* undefine rand and srand if you don't have random() from USENET */ X#define rand random X#define srand srandom X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int n; /* generate a permutation of {1,2,3,...,n} */ X int i; X int t; X char *mask; X X if (argc > 2 && strcmp(argv[1], "-s") == 0) { X t = atoi(argv[2]); X if (t < 16) X t = 1 << t; X srand(t); X argv++; X argv++; X } X n = atoi(argv[1]); X mask = (char *)malloc(n); X X for (i=0; i<n; i++) X mask[i] = '\0'; X for (i=0; i<n; i++) { X do { X t = rand() % n; X } while (mask[t]); X mask[t] = '\1'; X printf("%d ", t+1); X } X putchar('\n'); X exit(0); X} End-of-File-Grunt if test 724 -ne `cat 'mkperm.c' | wc -c` then echo 'shar: transmission error (expected 724 characters)' fi echo 'x - mkprofile' if test -f 'mkprofile' then echo 'shar: over-writing existing file mkprofile' fi sed 's/^X//' > mkprofile <<'End-of-File-Grunt' X#! /bin/sh X# Incomplete. X# $Header: mkprofile,v 1.2 87/06/23 17:07:28 kjmcdonell Beta $ X profilework) X echo "" X echo "Profile Work Load Test:" >>$LOG X rate=${rate-2} X echo "" >>$LOG X echo "Control parameters: rate=$rate script=script.1" >>$LOG X echo "" >>$LOG X if test ! -f makework X then X make makework X fi X if test ! -f keyb X then X make keyb X fi X tty=${tty-`tty`} X if test "$tty" = "not a tty" X then X tty=/dev/tty X fi X chmod +w script.1 X ed - script.1 <<EOF Xg/^R=/s/=.*/=$rate/ Xg/^C=/s,=.*,=$tty, Xg/^H=/s,=.*,=., Xg/PATH=/s,=[^:]*:,=`pwd`:, Xw Xq XEOF X chmod -w script.1 X log=`pwd`/log.profile X ( echo "export log;log=$log" ; sed \ X-e 's/^export/##&/' \ X-e 's/^cd/##&/' \ X-e 's,^\([^:][a-zA-Z0-9./]*\)[ ].*,time sh -cx '"'&'"' 2>>$log,' \ X-e "s/\('[^$][^$][^']*\)"'\$\$'"/\1'"'$$'"'/g" \ X-e "s/\('[^$][^$][^']*\)"'\$\$'"/\1'"'$$'"'/g" \ X-e "s/\('[^$][^$][^']*\)"'\$\$'"/\1'"'$$'"'/g" \ X-e "s/''//g" \ X-e 's/^##//' \ X-e 's/^\([a-zA-Z][a-zA-Z0-9]*\)=/export \1;&/' script.1 ) >script.1.time X s=`cat script.1 | wc -c` X ts=`cat script.1.time | wc -c` X rate=`echo "scale=2;$rate*$ts/$s" | bc` X ed - script.1.time << End-of-File Xg/R=/s/=.*/=$rate/ Xw Xq XEnd-of-File X echo "Profile run starts ..." X echo '/bin/sh -ie <script.1.time' >./Workload/workload.time X trap "./cleanup -w -i $i -t $tmp -a; exit" 1 2 3 4 5 6 7 8 9 10 12 13 14 15 X time ./makework -rc $rate $tty 1 <./Workload/workload.time >$tty 2>>$tmp X if test $? != 0 X then X# makework was aborted X cp $tmp Tmp/save.$n.abort X ./cleanup -w -i $i -t $tmp -a X exit X fi X ./cleanup -w -t $tmp X echo "" >>$LOG X echo "Profile run finished, collect and summarize results ..." X sed \ X-e 's/[ ]*\([0-9][0-9]*\.[0-9]*\) *real/real \1\ X/' \ X-e 's/[ ]*\([0-9][0-9]*\.[0-9]*\) *user/user \1\ X/' \ X-e 's/[ ]*\([0-9][0-9]*\.[0-9]*\) *sys/sys \1\ X/' \ X $log \ X | awk ' XBEGIN { printf "\t Real (percent)\t User (percent)\t Sys (percent)\n" } X/^\+/ { if ($2 != "keyb") { X c=$2 X cmd[c]=c X } X next X } X/^real/ { r[c]+=$2; totr+=$2; } X/^user/ { u[c]+=$2; totu+=$2; } X/^sys/ { s[c]+=$2; tots+=$2; } XEND { for (c in cmd) { X printf cmd[c] X printf "\t%6.1f (%5.2f%%)",r[c],100*r[c]/totr X printf "\t%6.1f (%5.2f%%)",u[c],100*u[c]/totu X printf "\t%6.1f (%5.2f%%)\n",s[c],100*s[c]/tots X } X printf "-------\n" X printf "Totals:\t%6.1f\t\t%6.1f\t\t%6.1f\n",totr,totu,tots X } ' >>$LOG X ;; X End-of-File-Grunt if test 2568 -ne `cat 'mkprofile' | wc -c` then echo 'shar: transmission error (expected 2568 characters)' fi echo 'x - mkscript' if test -f 'mkscript' then echo 'shar: over-writing existing file mkscript' fi sed 's/^X//' > mkscript <<'End-of-File-Grunt' X#! /bin/sh X# $Header: mkscript,v 1.2 87/06/22 14:35:54 kjmcdonell Beta $ X# create script files by permuting the job steps .. X# output files labelled script.n, n=1,2,... X Xif test $# -ne 2 Xthen X echo "Usage: mkscript n master-script" X exit 1 Xfi X Xn=$1 Xshift X Xif test ! -f $1 Xthen X echo "mkscript: cannot open \"$1\"" X exit 1 Xfi X Xns=`grep '^%%' $1 | wc -l` Xns=`expr $ns - 1` X Xk=1 Xwhile test $k -le $n Xdo X awk ' XBEGIN { '"`./mkperm -s $k $ns | sed 's/[0-9][0-9]*/perm[i++] = &;/g`"' nj=0 } XNR==1 { next } X/^%%/ { nj++; next } X { if (job[nj] == "") X job[nj] = $0 X else X job[nj] = job[nj] "\n" $0 X } XEND { print job[0] X for (i=0; i<'$ns'; i++) X print job[perm[i]] X print job[nj] X }' $1 > script.$k X k=`expr $k + 1` Xdone End-of-File-Grunt if test 722 -ne `cat 'mkscript' | wc -c` then echo 'shar: transmission error (expected 722 characters)' fi echo 'x - mkscript.out' if test -f 'mkscript.out' then echo 'shar: over-writing existing file mkscript.out' fi sed 's/^X//' > mkscript.out <<'End-of-File-Grunt' X#! /bin/sh X# try running a script a catching the output X# $Header: mkscript.out,v 1.3 87/06/24 15:13:57 kjmcdonell Beta $ Xcmdline=`sed 1q script.master | grep '^%W%' | sed 's/%W%[ ]*//'` Xif test "$cmdline" = "" Xthen X echo "mkscript.out: illegal %W% record at beginning of \"script.master\"" X exit 1 Xfi X Xmake clean context Xtty=/dev/null ; export tty Xmkdir .tmp Xcp * .tmp Xcd .tmp Xsed -e 1d -e '/^%%/d' script.master > script.1 Xif $cmdline <script.1 >script.out 2>&1 Xthen X : Xelse X cat script.out X echo "mkscript.out: fatal error" X exit 1 Xfi Xcat script.1 >>script.out Xmv script.out .. Xcd .. Xrm -rf .tmp End-of-File-Grunt if test 606 -ne `cat 'mkscript.out' | wc -c` then echo 'shar: transmission error (expected 606 characters)' fi echo 'x - mktbl' if test -f 'mktbl' then echo 'shar: over-writing existing file mktbl' fi sed 's/^X//' > mktbl <<'End-of-File-Grunt' X#! /bin/sh X# $Header: mktbl,v 1.4 87/09/17 06:10:39 kenj Exp $ X# make tbl source to summarize results. Xprog=$0 Xif test $# -ne 1 Xthen X echo Usage: $prog machine X exit 1 Xfi Xinit=`./mk1 $prog $1` Xtest $? != 0 && echo "$init" && exit 1 Xeval $init Xcat >$1 <<End-of-File-Grunt X.\" \$Compile: typeset -me -t %f X.nr tf 0 X.nr tp 10 X.nr pp 10 X.nr fp 10 X.ll 6.5i X.sz 10 X.he 'MUSBUS'Monash UNIX Benchmarking Suite'' X.fo '$MC''\*(td' X.(b X.TS Xdoublebox,center; Xl | l. XProcessor $MC X $OPT XMemory $MEM XUNIX Version $UNIX XTest Date $D XMUSBUS Version $V X.TE X.)b XEnd-of-File-Grunt Xecho "Disks: $DISKS" > disks X./mk2 $log \ X| soelim \ X| sed 's/^\([1-9][0-9]*\)_Users/\1/' >>$1 Xrm -f disks End-of-File-Grunt if test 669 -ne `cat 'mktbl' | wc -c` then echo 'shar: transmission error (expected 669 characters)' fi echo 'x - musbus.1' if test -f 'musbus.1' then echo 'shar: over-writing existing file musbus.1' fi sed 's/^X//' > musbus.1 <<'End-of-File-Grunt' X.\" $Header: musbus.1,v 1.1 87/09/03 06:13:59 kenj Exp $ X.TH MUSBUS 1 X.SH NAME XMUSBUS \- a multi-user performance evaluation tool X.SH SYNOPSIS X.B run X.ft R X[ option ] X.SH DESCRIPTION XMUSBUS is designed to support multi-user performance measurements Xthat are both realistic and comparable between machines Xand systems. XThe principal performance metric is the time (CPU and elapsed) Xrequired to perform a selected workload as a function Xof increasing concurrent load. X.PP XA description of the workload profile is one of the Xinputs to MUSBUS, and consequently MUSBUS is a benchmarking Xtool, rather than a benchmark X.I per se. X.PP XIn addition to the multi-user test, MUSBUS supports a battery Xof smaller tests designed to measure some aspect of hardware Xspeed or system implementation efficiency. XThese are diagnostic, rather than performance, tests. X.PP XEach MUSBUS execution is controlled by a collection Xof environment variables and the script X.I run Xthat performs error checking, repeated tests for statistical Xvalidity, set up and clean up. XParticular tests may be selected by options in the command line. X.SH FILES X.ta 12n XWorkload/* workload description X.br XTmp/* temporary files X.br XResults/* log files X.br XTools/* ancillary support tools X.SH DIAGNOSTICS X``Benchmark Aborted'' and associated bad news indicating why. X.SH "SEE ALSO" XKen J. McDonell: X.ft I XAn Introduction to the Monash Benchmark Suite (MUSBUS), X.ft R X(included in the MUSBUS distribution). X.br XKen J. McDonell: X.ft I XTaking Performance Evaluation Out of the ``Stone Age'', X.ft R XProceedings Summer Usenix Technical Conference, XPhoenix, Arizona, June, 1987, pp 407-417. End-of-File-Grunt if test 1639 -ne `cat 'musbus.1' | wc -c` then echo 'shar: transmission error (expected 1639 characters)' fi echo 'x - pipe.c' if test -f 'pipe.c' then echo 'shar: over-writing existing file pipe.c' fi sed 's/^X//' > pipe.c <<'End-of-File-Grunt' X/* X * pipe -- test single process pipe throughput (no context switching) X * X * $Header: pipe.c,v 3.5 87/06/22 14:32:36 kjmcdonell Beta $ X */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X char buf[512]; X int iter = 2048; /* 1M byte */ X int pvec[2]; X X pipe(pvec); X close(0); dup(pvec[0]); close(pvec[0]); X close(1); dup(pvec[1]); close(pvec[1]); X X while (iter-- > 0) { X if (write(1, buf, sizeof(buf)) != sizeof(buf)) X perror("write failed"); X if (read(0, buf, sizeof(buf)) != sizeof(buf)) X perror("read failed"); X } X exit(0); X} End-of-File-Grunt if test 534 -ne `cat 'pipe.c' | wc -c` then echo 'shar: transmission error (expected 534 characters)' fi echo 'x - precision.c' if test -f 'precision.c' then echo 'shar: over-writing existing file precision.c' fi sed 's/^X//' > precision.c <<'End-of-File-Grunt' X/* Program to determine properties of the arithmetic available. */ X/* Makes certain assumptions about the likely format of numbers */ X/* */ X/* Author: Steven Pemberton, CWI, Amsterdam. steven@mcvax */ X/* */ X/* If your C system is not unix but does have signal/setjmp, */ X/* add a #define unix */ X/* You may also need to change the #include <sys/signal.h> line */ X/* and add some calls to signal(). */ X/* X * $Header: precision.c,v 3.5 87/08/06 08:10:59 kenj Exp $ X */ X X#ifdef unix X X#define SIGNAL X X#include <sys/signal.h> X#include <setjmp.h> X Xjmp_buf lab; Xoverflow(sig) int sig; { /*what to do on overflow*/ X signal(sig, overflow); X longjmp(lab, 1); X} X X#endif X Xint tenlog(v) double v; { X /*The largest power of ten less than v*/ X int p=0; X while (v>10) { p++; v/=10; } X return p; X} X Xint two(v) int v; { X /* (the closest power of two to v)-1 */ X int t=1, s; X while (t<v) t=t*2+1; X s=(t-1)/2; X if ((v-s)>(t-v)) return(t); X return(s); X} X Xdouble twopower(n, e) int n, *e; { X /* Calculate 2**n without overflow worries */ X /* Result is r*10**e */ X double r=1.0; *e=0; X while (n-- > 0) { X r*=2.0; X if (r>10.0) { r/=10.0; (*e)++; } X } X return(r); X} X Xmain() { X short maxshort, newshort; X int maxint, newint, i, maxfexp, maxdexp, bits, X fmantis, dmantis, ddmantis, X shortpower, intpower, longpower, X fpower, dpower, fipower, dipower, ddipower, lpower, base; X long maxlong, newlong; X float maxfloat, newfloat, sum, f, maxifloat; X double maxdouble, newdouble, maxidouble, maxiexpr, X d, incr, dsum; X X#ifdef SIGNAL X signal(SIGFPE, overflow); /*signal(SIGOVER, overflow);*/ X#endif X X/****** Calculate max short *********************************************/ X/* Calculate 2**n-1 until overflow - then use the previous value */ X X newshort=1; maxshort=0; X#ifdef SIGNAL X if (setjmp(lab)==0) X#endif X for(shortpower=0; newshort>maxshort; shortpower++) { X maxshort=newshort; X newshort=newshort*2+1; X } X bits= (shortpower+1)/sizeof(short); X printf("maxshort=%d (=2**%d-1)\n", maxshort, shortpower); X X/****** Calculate max int by the same method ***************************/ X X newint=1; maxint=0; X#ifdef SIGNAL X if (setjmp(lab)==0) X#endif X for(intpower=0; newint>maxint; intpower++) { X maxint=newint; X newint=newint*2+1; X } X printf("maxint=%d (=2**%d-1)\n", maxint, intpower); X X/****** Calculate max long by the same method ***************************/ X X newlong=1; maxlong=0; X#ifdef SIGNAL X if (setjmp(lab)==0) X#endif X for(longpower=0; newlong>maxlong; longpower++) { X maxlong=newlong; X newlong=newlong*2+1; X } X printf("maxlong=%ld (=2**%d-1)\n", maxlong, longpower); X X/****** Calculate max float, assuming it's a power of two ***************/ X/* Calculate 2**i until it overflows, and then use the nearest */ X/* power of two (some machines overflow early, some late) */ X X newfloat=1; maxfloat=0; X#ifdef SIGNAL X if (setjmp(lab)==0) X#endif X for(i=0;newfloat>maxfloat;i++) { X maxfloat=newfloat; X newfloat=newfloat*2; X } X maxfexp=two(i); maxfloat=twopower(maxfexp, &fpower); X printf("maxfloat=~%fE%d (=~2**%d) (%d bits)\n", X maxfloat, fpower, maxfexp, sizeof(float)*bits); X X/****** Calculate max double, assuming it's a power of two **************/ X X newdouble=1; maxdouble=0; X#ifdef SIGNAL X if (setjmp(lab)==0) X#endif X for(i=0;newdouble>maxdouble;i++) { X maxdouble=newdouble; X newdouble*=2; X } X#ifdef SIGNAL X if (setjmp(lab)!=0) { printf("\nUnexpected overflow\n"); exit(1); } X#endif X maxdexp=two(i); maxdouble=twopower(maxdexp, &dpower); X printf("maxdouble=~%fE%d (=~2**%d) (%d bits)\n", X maxdouble, dpower, maxdexp, sizeof(double)*bits); X X/****** Calculate the accuracy for float, double, and expressions *******/ X/* maxintfloat and maxintdouble are the largest values that can */ X/* still be integer values; ie such that (x+1)-x=1. */ X/* Some systems really do use extra precision in expressions */ X X f=2.0; incr=1.0; sum=f+incr; X for (fmantis=0; sum>2.0; fmantis++) { incr/=2; sum=f+incr; } X printf("max float exp=%d mantissa bits=%d\n", maxfexp, fmantis); X X d=2.0; incr=1.0; dsum=d+incr; X for (dmantis=0; dsum>2.0; dmantis++) { incr/=2; dsum=d+incr; } X printf("max double exp=%d mantissa bits=%d\n", maxdexp, dmantis); X X d=2.0; incr=1.0; X for (ddmantis=0; d+incr>2.0; ddmantis++) incr/=2; X X maxifloat=twopower(fmantis, &fipower); X printf("maxintfloat=~%fE%d (=2**%d-1) (%d digit precision)\n", X maxifloat, fipower, fmantis, fipower); X X maxidouble=twopower(dmantis, &dipower); X printf("maxintdouble=~%fE%d (=2**%d-1) (%d digit precision)\n", X maxidouble, dipower, dmantis, dipower); X X maxiexpr=twopower(ddmantis, &ddipower); X printf("maxint for expressions=~%fE%d (=2**%d-1) (%d digit precision)\n", X maxiexpr, ddipower, ddmantis, ddipower); X X/****** BASE is the largest power of ten such that BASE*BASE can be */ X/* computed exactly as a double, and BASE+BASE as a long, useful */ X/* for multi-length arithmetic */ X X lpower= tenlog((double)(maxlong/2)); X base= (dipower/2)>lpower?lpower:(dipower/2); X printf("BASE=1E%d\n", base); X X exit(0); X} End-of-File-Grunt if test 5003 -ne `cat 'precision.c' | wc -c` then echo 'shar: transmission error (expected 5003 characters)' fi echo 'x - run' if test -f 'run' then echo 'shar: over-writing existing file run' fi sed 's/^X//' > run <<'End-of-File-Grunt' X#! /bin/sh Xversion="5.0" X# X# General Purpose Benchmark X# Ken McDonell, Computer Science, Monash University X# August 1, 1983 X# X# $Header: run,v 3.13 87/09/17 06:09:50 kenj Exp $ X# X# You will need ... X# Level 7 shell X# awk cat cc chmod comm cp date dc df echo ed expr X# kill ls make mkdir rm sed test time touch tty who X# X# The following variables may be assigned external values to overide defaults X# X# Test Variable Default Use X# all iterations 6 repeat count for timing X# arithmetic arithloop 1000 no. of summations X# hanoi ndisk 17 list of nos. of disks X# syscall ncall 4000 no. iterations, each of X# 5 system calls X# context1 switch1 500 no. of switches X# pipe io 2048 no. 512 byte blocks to X# read and write X# spawn children 100 no. of child processes X# execl nexecs 100 no. of execs X# randmem,seqmem arrays 8 64 512 list or array sizes X# poke 100000 no. array accesses X# fstime blocks 62 125 250 500 list of file sizes X# where . directory for files X# need 2 x max[ $blocks ] X# work nusers 1 4 8 16 24 32 list of nos. of users X# rate 2 per user input rate X# [ chars / sec ] X# ttys /dev/tty list of devices where X# output goes X# dirs . list of directories for X# creation of temp work X# Xif make source install Xthen X : Xelse X echo "run: something is very wrong here .. initial make failed" X exit 1 Xfi Xecho "kill -9 $$" > Tmp/kill_run ; chmod u+x Tmp/kill_run Xif test $# -eq 0 Xthen X set - arithoh register short int long float double dc hanoi \ X syscall pipe context1 spawn execl \ X C seqmem randmem fstime work Xelif test "$1" = "arithmetic" Xthen X set - arithoh register short int long float double dc Xfi Xiter=${iterations-6} Xdate=`date` Xtmp=Tmp/$$.tmp Xlog=Results/log Xlogwork=Results/log.work Xecho "" >>$log Xecho "Start Benchmark Run (MUSBUS Version $version)" >>$log Xecho " $date (long iterations $iter times)" >>$log Xecho " " `who | wc -l` "interactive users." >>$log Xif test $iter -eq 6 Xthen X longloop="1 2 3 4 5 6" X shortloop="1 2 3" Xelse X short=`expr \( $iter + 1 \) / 2` X longloop="" X shortloop="" X while test $iter -gt 0 X do X longloop="$iter $longloop" X if test $iter -le $short X then X shortloop="$iter $shortloop" X fi X iter=`expr $iter - 1` X done Xfi Xif test ! -f iamalive Xthen X make iamalive Xfi Xfor test Xdo X need=$test X prog=./$test X paramlist="#" X parammsg="" X repeat="$longloop" X stdout="$log" X stdin="" X cleanopt="-t $tmp" X trap "./cleanup -l $log -a; exit" 1 2 3 15 X echo $test: X echo "" >>$log X case $test X in X X arithoh|register|short|int|long|float|double) X options=${arithloop-1000} X logmsg="Arithmetic Test (type = $test): $options Iterations" X ;; X X dc) need=dc.dat X prog=dc X options="" X stdin=dc.dat X stdout=/dev/null X logmsg="Arithmetic Test (sqrt(2) with dc to 99 decimal places)" X ;; X X hanoi) options='$param' X stdout=/dev/null X logmsg="Recursion Test: Tower of Hanoi Problem" X paramlist="${ndisk-17}" X parammsg='$param Disk Problem:' X ;; X X syscall) X options=${ncall-4000} X logmsg="System Call Overhead Test: 5 x $options Calls" X ;; X X context1) X options=${switch1-500} X logmsg="Pipe-based Context Switching Test: 2 x $options Switches" X ;; X X pipe) options=${io-2048} X logmsg="Pipe Throughput Test: read & write $options x 512 byte blocks" X ;; X X spawn) options=${children-100} X logmsg="Process Creation Test: $options forks" X ;; X X execl) options=${nexecs-100} X logmsg="Execl Throughput Test: $options execs" X ;; X X randmem|seqmem) X type=Random X if test $test = seqmem X then X type=Sequential X fi X poke=${poke-100000} X options='-s$param '"-n$poke" X logmsg="$type Memory Access Test: $poke Accesses" X paramlist=${arrays-"8 64 512"} X parammsg='Array Size: $param Kbytes' X cleanopt="-m $tmp" X ;; X X fstime) repeat="$shortloop" X where=${where-Tmp} X options='$param '"$where" X logmsg="Filesystem Throughput Test:" X paramlist=${blocks-"62 125 250 500"} X parammsg='File Size: $param blocks' X cleanopt="-f $tmp" X ;; X X C) need=cctest.c X prog=cc X options='$param' X stdout=/dev/null X repeat="$shortloop" X logmsg="C Compiler Test:" X paramlist="-c_cctest.c cctest.o" X parammsg='cc $param' X rm -f cctest.o a.out X ;; X X work|x) X ttys=${ttys-`tty`} X if test "$ttys" = "not a tty" X then X ttys=/dev/tty X fi X tty=`echo $ttys | sed 's/ .*//'` ; export tty X rate=${rate-2} ; export rate X dirs=${dirs-Tmp} X scripts=`echo Tmp/script.?` X need="makework keyb" X prog=./makework X options='$param' X stdin=Tmp/workload X stdout=`echo $ttys | sed 's/ .*//'` X repeat="$shortloop" X logmsg="Simulated Multi-user Work Load Test:" X paramlist=${nusers-"1 4 8 16 24 32"} X parammsg='$param Concurrent Users, each with Input Keyboard Rate $rate chars / sec' X cleanopt="-w -t $tmp" X maxusers=`echo $paramlist | awk '{for (i=1;i<=NF;i++) if ($i > maxu) maxu=$i; print maxu}'` X if test $test = work X then X ./iamalive "Check job streams and workload description ..." X if make script ttychk clock >/dev/null 2>$tmp X then X : X else X cat $tmp X cat $tmp >>$log X ./cleanup -l $log -r "\"make script\" failed!" -a X exit 1 X fi X cmdline=`sed 1q Workload/script.master | sed 's/%W%[ ]*//'` X rm -f Tmp/workload X touch Tmp/workload X ( echo $dirs; echo $scripts; echo $ttys ) \ X | awk ' X NR==1 { for (i=1;i<=NF;i++) dir[i]=$i;nd=NF } X NR==2 { for (i=1;i<=NF;i++) script[i]=$i;ns=NF } X NR==3 { for (i=1;i<=NF;i++) tty[i]=$i;nt=NF } X END { for (i=0;i<'$maxusers';i++) X print dir[i%nd+1] "/user" i " '"$cmdline"' <" script[i%ns+1] " >" tty[i%nt+1] }' \ X >>Tmp/workload X echo "done." X ./iamalive "Check tty bandwidth ..." X inch=`cat Tmp/script.1 | wc -c` X outch=`cat Tmp/script.out | wc -c` X nscript=`echo Tmp/script.? | wc -w` X orate=`expr $rate \* $outch / $inch` X if ./ttychk $maxusers $orate $nscript $ttys 2>$tmp X then X echo "OK." X else X echo "FAILED!" X cat $tmp X cat $tmp >>$log X rm -f $tmp X ./cleanup -l $log -a X exit 1 X fi X fi X ./iamalive "Set up work directories ..." X cd Workload X if make context >/dev/null 2>../$tmp X then X cd .. X else X cd .. X cat $tmp X cat $tmp >>$log X rm -f $tmp X ./cleanup -l $log -r "\"make context\" failed in Workload" -a X exit 1 X fi X for dir in `sed 's/ .*//' Tmp/workload` X do X rm -rf $dir X mkdir $dir X cp Workload/* $dir X done X echo "done." X echo "" >>$log X echo "Output sent to ... $ttys" >>$log X echo "Directories for temporary files ... $dirs" >>$log X echo "" >>$log X df >>$log X echo "" >>$log X if test $test = work X then X ./iamalive '60 second wallclock accuracy check ...' X echo "SIGALRM check: " `./clock` >>$log X echo "done." X fi X echo "This test generates lots of tty output" X ;; X X *) ./cleanup -l $log -r "run: unknown test \"$test\"" -a X exit 1 X ;; X esac X for file in $need X do X if make $need >/dev/null 2>$tmp X then X : X else X cat $tmp X cat $tmp >>$log X rm -f $tmp X ./cleanup -l $log -r "\"make $need\" failed!" -a X exit 1 X fi X done X echo "$logmsg" >>$log X for param in $paramlist X do X param=`echo $param | sed 's/_/ /g'` X ./iamalive " [$param] -" X eval msg='"'$parammsg'"' X eval opt='"'$options'"' X if test "$msg" != "" X then X echo "" >>$log X echo "$msg" >>$log X fi X rm -f $tmp X for i in $repeat X do X trap "./cleanup -l $log -i $i $cleanopt -a; exit" 1 2 3 15 X ./iamalive $i X if test "$stdin" = "" X then X time $prog $opt 2>>$tmp >>$stdout X else X time $prog $opt <$stdin 2>>$tmp >>$stdout X fi X status=$? X if test $status != 0 X then X if test -f $tmp X then X cp $tmp Tmp/save.$test.$param X ./cleanup -l $log -i $i $cleanopt -r "run: test=$test param=$param fatalstatus=$status" -a X else X ./cleanup -l $log -r "run: test=$test param=$param fatalstatus=$status" -a X fi X exit X fi X test $prog = makework && ./cleanup -w X done X ./cleanup -l $log $cleanopt X done X case $test X in X C) X rm -f cctest.o a.out X ;; X work|x) X echo "Check for corpses ... " >>$logwork X if test "`echo Tmp/*.tmp`" != 'Tmp/*.tmp' X then X echo "Unclaimed temporary workfiles?" >>$logwork X ls -l Tmp/*.tmp >>$logwork X fi X ( cd Workload ; ls ) >/tmp/work$$ X for dir in `sed 's/ .*//' Tmp/workload` X do X ( cd $dir ; ls ) >/tmp/user$$ X comm -23 /tmp/work$$ /tmp/user$$ >/tmp/x$$ X if test -s /tmp/x$$ X then X echo "Files missing from $dir ..." >>$logwork X echo " " `cat /tmp/x$$` >>$logwork X fi X comm -13 /tmp/work$$ /tmp/user$$ >/tmp/x$$ X if test -s /tmp/x$$ X then X echo "Extra files in $dir ..." >>$logwork X echo " " `cat /tmp/x$$` >>$logwork X fi X rm -rf $dir X done X rm -f /tmp/*$$ X ;; X esac X echo "" Xdone Xecho "" >>$log Xecho " " `who | wc -l` "interactive users." >>$log Xecho "End Benchmark Run ($date) ...." >>$log Xecho "End Benchmark Run ($date) ...." Xexit End-of-File-Grunt if test 9021 -ne `cat 'run' | wc -c` then echo 'shar: transmission error (expected 9021 characters)' fi echo 'x - script.master' if test -f 'script.master' then echo 'shar: over-writing existing file script.master' fi sed 's/^X//' > script.master <<'End-of-File-Grunt' X%W% /bin/sh -ie Xmkdir /tmp/$$ tmp X%% 1 edit X./keyb edscr1.dat | ed edit.dat X: ....................................................... X: . This is some filler of about the same . X: . size as the file edscr1.dat, since the . X: . emulated input proceeds in parallel, and . X: . we want the real-time delay to be about right . X: ....................................................... Xchmod u+w temporary Xrm temporary X%% 2 ls Xls -l X%% 3 cat Xcat cat.dat X%% 4 compile Xcc -c cctest.c 1>&2 Xrm *.o X%% 5 edit, compile and link Xchmod 444 dummy.c X./keyb edscr2.dat | ed dummy.c X: . more textual and time filler for the second edscript file, edscr2.dat . Xcc dummy.c 1>&2 Xrm a.* grunt.c X%% 6 grep Xgrep '[ ]*nwork' grep.dat X%% 7 file copying Xcp *.c edit.dat /tmp/$$ Xcp /tmp/$$/* tmp X%% Xrm -rf tmp /tmp/$$ End-of-File-Grunt if test 835 -ne `cat 'script.master' | wc -c` then echo 'shar: transmission error (expected 835 characters)' fi echo 'x - spawn.c' if test -f 'spawn.c' then echo 'shar: over-writing existing file spawn.c' fi sed 's/^X//' > spawn.c <<'End-of-File-Grunt' X/* X * Process creation X * X * $Header: spawn.c,v 3.4 87/06/22 14:32:48 kjmcdonell Beta $ X */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int iter; X int slave; X int status; X X if (argc != 2) { X printf("Usage: %s count\n", argv[0]); X exit(1); X } X X iter = atoi(argv[1]); X X while (iter-- > 0) { X if ((slave = fork()) == 0) { X /* slave .. boring */ X#if debug X printf("fork OK\n"); X#endif X exit(0); X } else if (slave < 0) { X /* woops ... */ X printf("Fork failed at iteration %d\n", iter); X perror("Reason"); X exit(2); X } else X wait(&status); X if (status != 0) { X printf("Bad wait status: 0x%x\n", status); X exit(2); X } X#if debug X printf("Child %d done.\n", slave); X#endif X } X exit(0); X} End-of-File-Grunt if test 710 -ne `cat 'spawn.c' | wc -c` then echo 'shar: transmission error (expected 710 characters)' fi echo 'x - syscall.c' if test -f 'syscall.c' then echo 'shar: over-writing existing file syscall.c' fi sed 's/^X//' > syscall.c <<'End-of-File-Grunt' X/* X * syscall -- sit in a loop calling the system X * X * $Header: syscall.c,v 3.4 87/06/22 14:32:54 kjmcdonell Beta $ X */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int iter; X int i; X X if (argc != 2) { X printf("Usage: %s count\n", argv[0]); X exit(1); X } X X iter = atoi(argv[1]); X X while (iter-- > 0) { X close(dup(0)); X getpid(); X getuid(); X umask(022); X } X exit(0); X} End-of-File-Grunt if test 377 -ne `cat 'syscall.c' | wc -c` then echo 'shar: transmission error (expected 377 characters)' fi echo 'x - tbl.1' if test -f 'tbl.1' then echo 'shar: over-writing existing file tbl.1' fi sed 's/^X//' > tbl.1 <<'End-of-File-Grunt' X.(b X.TS Xbox,center; Xc s s Xc | c | c Xc | c | c Xl | n | n. XRaw Speed X_ X Elapsed CPU XTest Description Time Time X_ End-of-File-Grunt if test 111 -ne `cat 'tbl.1' | wc -c` then echo 'shar: transmission error (expected 111 characters)' fi echo 'x - tbl.2' if test -f 'tbl.2' then echo 'shar: over-writing existing file tbl.2' fi sed 's/^X//' > tbl.2 <<'End-of-File-Grunt' X.(b X.TS Xbox,center; Xc s s. XMemory Throughput X(1000s integer accesses per sec.) X_ X.T& Xc | c | c Xc | c | c Xn | n | n. XArray Size X(K bytes) Sequential Random X_ End-of-File-Grunt if test 157 -ne `cat 'tbl.2' | wc -c` then echo 'shar: transmission error (expected 157 characters)' fi echo 'x - tbl.3' if test -f 'tbl.3' then echo 'shar: over-writing existing file tbl.3' fi sed 's/^X//' > tbl.3 <<'End-of-File-Grunt' X.(b X.TS Xbox,center; Xc s s s. XFilesystem Throughput (Kchars per sec.) End-of-File-Grunt if test 69 -ne `cat 'tbl.3' | wc -c` then echo 'shar: transmission error (expected 69 characters)' fi echo 'x - tbl.4' if test -f 'tbl.4' then echo 'shar: over-writing existing file tbl.4' fi sed 's/^X//' > tbl.4 <<'End-of-File-Grunt' X_ X.T& Xc | c | c | c Xl | n | n | n. XFile Size Write Read Copy X_ End-of-File-Grunt if test 63 -ne `cat 'tbl.4' | wc -c` then echo 'shar: transmission error (expected 63 characters)' fi echo 'x - tbl.5' if test -f 'tbl.5' then echo 'shar: over-writing existing file tbl.5' fi sed 's/^X//' > tbl.5 <<'End-of-File-Grunt' X.(b X.TS Xbox,center; Xc s s Xc | c | c Xn | n | n. XSimulated Work Load X_ XUsers Elapsed Time CPU Time X_ End-of-File-Grunt if test 99 -ne `cat 'tbl.5' | wc -c` then echo 'shar: transmission error (expected 99 characters)' fi echo 'x - time.awk' if test -f 'time.awk' then echo 'shar: over-writing existing file time.awk' fi sed 's/^X//' > time.awk <<'End-of-File-Grunt' X# $Header: time.awk,v 3.4 87/06/22 14:28:09 kjmcdonell Beta $ X/real/ { if (!fail) { X real+=$1; r2+=$1*$1; user+=$3; sys+=$5; c=$3+$5; c2+=c*c X ok++ X } X iter++; fail=0; next X } X { print "** Iteration ",iter+1," Failed: ",$0; fail=1 } XEND { X if (fail) iter++ X if (ok != iter) { X printf "For %d successful iterations from %d attempts ...\n",ok,iter X iter=ok X } 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 cpu=sys+user X printf "\nCPU Time: %.2f seconds [ %.2fu + %.2fs ]",cpu/iter,user/iter,sys/iter X if (iter > 1) printf " (variance %.3f)",(c2-2*cpu*cpu/iter+cpu*cpu/iter)/(iter-1) X print X } else { X print "Elapsed Time: -- no measured results!!" X print "CPU Time: -- no measured results!!" X } X } End-of-File-Grunt if test 864 -ne `cat 'time.awk' | wc -c` then echo 'shar: transmission error (expected 864 characters)' fi echo 'x - ttychk.c' if test -f 'ttychk.c' then echo 'shar: over-writing existing file ttychk.c' fi sed 's/^X//' > ttychk.c <<'End-of-File-Grunt' X/* X * X * Checks for tty accessability and bandwidth saturation. X * X * $Header: ttychk.c,v 3.6 87/06/22 14:32:58 kjmcdonell Beta $ X */ X X#include <stdio.h> X#include <sgtty.h> X#include <signal.h> X Xstruct { X int baud; /* baud rate */ X int symb; /* symbolic constant for baud rate */ X} bmap[] = { X { 300, B300 }, X { 1200, B1200 }, X { 2400, B2400 }, X { 4800, B4800 }, X { 9600, B9600 }, X { 0, 0 } X}; Xint status = 0; /* exit() status */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X struct sgttyb ttyb; X int nusers; /* number of simulated users */ X int nscript; /* number of script files */ X int baud = 0; /* aggregate baud rate across X active ttys */ X int br; X int nttys; /* number of active ttys */ X int i; X int fd; X int l; X float orate; /* estimated output rate per user */ X int onalarm(); X X if (argc < 5) { X fprintf(stderr, "Usage: ttychk nusers orate nscript ttydev ... \n"); X exit(1); X } X nusers = atoi(argv[1]); X if (nusers < 1) { X fprintf(stderr, "ttychk: nusers must be > 0\n"); X status |= 1; X } X sscanf(argv[2], "%f", &orate); X nscript = atoi(argv[3]); X if (nscript < 1) { X fprintf(stderr, "ttychk: nscript must be > 0\n"); X status |= 1; X } X X nttys = nusers <= nscript ? nusers : nscript; X X signal(SIGALRM, onalarm); X for (i = 4; i < argc && nttys; i++, nttys--) { X alarm(3); X if ((fd = open(argv[i], 1)) < 0) { X fprintf(stderr, "ttychk: cannot open %s for writing\n", X argv[i]); X perror(""); X status |= 1; X continue; X } X alarm(0); X if (ioctl(fd, TIOCGETP, &ttyb) < 0) { X fprintf(stderr, "ttychk: cannot stat %s\n", X argv[i]); X perror(""); X status |= 1; X close(fd); X continue; X } X close(fd); X br = 0; X for (l = 0; bmap[l].baud; l++) { X if (bmap[l].symb == ttyb.sg_ospeed) { X br = bmap[l].baud; X break; X } X } X#ifdef DEBUG X fprintf(stderr, "%s: %d baud\n", argv[i], br); X#endif X if (br != 9600) X fprintf(stderr, "ttychk: Warning - baud rate at %d for %s\n", X br, argv[i]); X baud += br; X } X nttys = nusers <= nscript ? nusers : nscript; X#ifdef DEBUG X fprintf(stderr, "aggregate tty bandwidth: %d baud\n", baud); X fprintf(stderr, "aggregate tty output rate: %d chars/sec (for %d ttys)\n", (int)(orate*nusers), nttys); X#endif X X /* assume 10 bits per character, and the 50% figure is arbitrary! */ X if (nusers*orate > 0.5*(baud/10)) { X fprintf(stderr, "ttychk panic: Total tty output rate (%d chars/sec) exceeds 50%% of\n total tty bandwidth (%d chars/sec)\n", X (int)(nusers*orate), baud/10); X status |= 1; X } X X exit(status); X} X Xonalarm() X{ X status |= 1; X} End-of-File-Grunt if test 2564 -ne `cat 'ttychk.c' | wc -c` then echo 'shar: transmission error (expected 2564 characters)' fi echo 'x - util.c' if test -f 'util.c' then echo 'shar: over-writing existing file util.c' fi sed 's/^X//' > util.c <<'End-of-File-Grunt' X#include "makework.h" X#ifndef lint Xstatic char RCSid[] = "$Header: util.c,v 1.3 87/06/23 15:56:41 kjmcdonell Beta $"; 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 < nstream; i++) { X if (work[i].pid > 0 && kill(work[i].pid, SIGKILL) != -1) { X fprintf(stderr, "pid %d killed off\n", work[i].pid); X fflush(stderr); X } X } X exit_status = 4; X return; X} X X#ifdef DEBUG Xdumpwork() X{ X int i; X int j; X X for (i = 0; i < nstream; i++) { X fprintf(stderr, "job %d: cmd: %s home: %s tty: %s\n", X i, work[i].cmd, work[i].home, work[i].tty); 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].blen); X if (work[i].buf == (char *)0) X fprintf(stderr, "<NULL>\n"); X else { X register char *pend; X char *p; X char c; X p = work[i].buf; 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 End-of-File-Grunt if test 1146 -ne `cat 'util.c' | wc -c` then echo 'shar: transmission error (expected 1146 characters)' fi