[comp.sources.unix] v11i032: MUSBUS 5.0 -- Monash University Benchmark, Part04/04

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