#! /bin/sh
version="5.0"
#
# General Purpose Benchmark
# Ken McDonell, Computer Science, Monash University
# August 1, 1983
#
# $Header: run,v 3.13 87/09/17 06:09:50 kenj Exp $
#
#  You will need ...
#	Level 7 shell
#	awk cat cc chmod comm cp date dc df echo ed expr
#	kill ls make mkdir rm sed test time touch tty who
#
#  The following variables may be assigned external values to overide defaults
#
#	Test		Variable	Default		Use
#	all		iterations	6		repeat count for timing
#	arithmetic	arithloop	1000		no. of summations
#	hanoi		ndisk		17		list of nos. of disks
#	syscall		ncall		4000		no. iterations, each of
#							5 system calls
#	context1	switch1		500		no. of switches
#	pipe		io		2048		no. 512 byte blocks to
#							read and write
#	spawn		children	100		no. of child processes
#	execl		nexecs		100		no. of execs
#	randmem,seqmem	arrays		8 64 512	list or array sizes
#			poke		100000		no. array accesses
#	fstime		blocks		62 125 250 500	list of file sizes
#			where		.		directory for files
#							need 2 x max[ $blocks ]
#	work		nusers		1 4 8 16 24 32 	list of nos. of users
#			rate		2		per user input rate
#							[ chars / sec ]
#			ttys		/dev/tty	list of devices where
#							output goes
#			dirs		.		list of directories for
#							creation of temp work
#
if make source install
then
	:
else
	echo "run: something is very wrong here .. initial make failed"
	exit 1
fi
echo "kill -9 $$" > Tmp/kill_run ; chmod u+x Tmp/kill_run
if test $# -eq 0
then
	set -	arithoh register short int long float double dc hanoi \
		syscall pipe context1 spawn execl \
		C seqmem randmem fstime work
elif test "$1" = "arithmetic"
then
	set -	arithoh register short int long float double dc
fi
iter=${iterations-6}
date=`date`
tmp=Tmp/$$.tmp
log=Results/log
logwork=Results/log.work
echo "" >>$log
echo "Start Benchmark Run (MUSBUS Version $version)" >>$log
echo "  $date (long iterations $iter times)" >>$log
echo " " `who | wc -l` "interactive users." >>$log
if test $iter -eq 6
then
	longloop="1 2 3 4 5 6"
	shortloop="1 2 3"
else
	short=`expr \( $iter + 1 \) / 2`
	longloop=""
	shortloop=""
	while test $iter -gt 0
	do
		longloop="$iter $longloop"
		if test $iter -le $short
		then
			shortloop="$iter $shortloop"
		fi
		iter=`expr $iter - 1`
	done
fi
if test ! -f iamalive
then
    make iamalive
fi
for test
do
    need=$test
    prog=./$test
    paramlist="#"
    parammsg=""
    repeat="$longloop"
    stdout="$log"
    stdin=""
    cleanopt="-t $tmp"
    trap "./cleanup -l $log -a; exit" 1 2 3 15
    echo $test:
    echo "" >>$log
    case $test
    in

	arithoh|register|short|int|long|float|double)
		options=${arithloop-1000}
		logmsg="Arithmetic Test (type = $test): $options Iterations"
		;;

	dc)     need=dc.dat
		prog=dc
		options=""
		stdin=dc.dat
		stdout=/dev/null
		logmsg="Arithmetic Test (sqrt(2) with dc to 99 decimal places)"
		;;

	hanoi)	options='$param'
		stdout=/dev/null
		logmsg="Recursion Test: Tower of Hanoi Problem"
		paramlist="${ndisk-17}"
		parammsg='$param Disk Problem:'
		;;

	syscall)
		options=${ncall-4000}
		logmsg="System Call Overhead Test: 5 x $options Calls"
		;;

	context1)
		options=${switch1-500}
		logmsg="Pipe-based Context Switching Test: 2 x $options Switches"
		;;

	pipe)   options=${io-2048}
		logmsg="Pipe Throughput Test: read & write $options x 512 byte blocks"
		;;

	spawn)  options=${children-100}
		logmsg="Process Creation Test: $options forks"
		;;

	execl)  options=${nexecs-100}
		logmsg="Execl Throughput Test: $options execs"
		;;

	randmem|seqmem)
		type=Random
		if test $test = seqmem
		then
			type=Sequential
		fi
		poke=${poke-100000}
		options='-s$param '"-n$poke"
		logmsg="$type Memory Access Test: $poke Accesses"
		paramlist=${arrays-"8 64 512"}
		parammsg='Array Size: $param Kbytes'
		cleanopt="-m $tmp"
		;;

	fstime) repeat="$shortloop"
		where=${where-Tmp}
		options='$param '"$where"
		logmsg="Filesystem Throughput Test:"
		paramlist=${blocks-"62 125 250 500"}
		parammsg='File Size: $param blocks'
		cleanopt="-f $tmp"
		;;

	C)      need=cctest.c
		prog=cc
		options='$param'
		stdout=/dev/null
		repeat="$shortloop"
		logmsg="C Compiler Test:"
		paramlist="-c_cctest.c cctest.o"
		parammsg='cc $param'
		rm -f cctest.o a.out
		;;

	work|x)
		ttys=${ttys-`tty`}
		if test "$ttys" = "not a tty"
		then
		    ttys=/dev/tty
		fi
		tty=`echo $ttys | sed 's/ .*//'` ; export tty
		rate=${rate-2} ; export rate
		dirs=${dirs-Tmp}
		scripts=`echo Tmp/script.?`
		need="makework keyb"
		prog=./makework
		options='$param'
		stdin=Tmp/workload
		stdout=`echo $ttys | sed 's/ .*//'`
		repeat="$shortloop"
		logmsg="Simulated Multi-user Work Load Test:"
# Changed by C.Kirkby, more than 8 users takes too long to run
#		paramlist=${nusers-"1 4 8 16 24 32"}
		paramlist=${nusers-"1 4 8"}
		parammsg='$param Concurrent Users, each with Input Keyboard Rate $rate chars / sec'
		cleanopt="-w -t $tmp"
		maxusers=`echo $paramlist | awk '{for (i=1;i<=NF;i++) if ($i > maxu) maxu=$i; print maxu}'`
		if test $test = work
		then
		    ./iamalive "Check job streams and workload description ..."
		    if make script ttychk clock >/dev/null 2>$tmp
		    then
			:
		    else
			cat $tmp
			cat $tmp >>$log
			./cleanup -l $log -r "\"make script\" failed!" -a
			exit 1
		    fi
		    cmdline=`sed 1q Workload/script.master | sed 's/%W%[ 	]*//'`
		    rm -f Tmp/workload
		    touch Tmp/workload
		    ( echo $dirs; echo $scripts; echo $ttys ) \
		    | awk '
		    NR==1 { for (i=1;i<=NF;i++) dir[i]=$i;nd=NF }
		    NR==2 { for (i=1;i<=NF;i++) script[i]=$i;ns=NF }
		    NR==3 { for (i=1;i<=NF;i++) tty[i]=$i;nt=NF }
		    END   { for (i=0;i<'$maxusers';i++)
			     print dir[i%nd+1] "/user" i " '"$cmdline"' <" script[i%ns+1] " >" tty[i%nt+1] }' \
			>>Tmp/workload
		    echo "done."
		    ./iamalive "Check tty bandwidth ..."
		    inch=`cat Tmp/script.1 | wc -c`
		    outch=`cat Tmp/script.out | wc -c`
		    nscript=`echo Tmp/script.? | wc -w`
		    orate=`expr $rate \* $outch / $inch`
		    if ./ttychk $maxusers $orate $nscript $ttys 2>$tmp
		    then
		        echo "OK."
		    else
			echo "FAILED!"
			cat $tmp
			cat $tmp >>$log
			rm -f $tmp
			./cleanup -l $log -a
			exit 1
		    fi
		fi
		./iamalive "Set up work directories ..."
		cd Workload 
	        if make context >/dev/null 2>../$tmp
		then
		    cd ..
		else
		    cd ..
		    cat $tmp
		    cat $tmp >>$log
		    rm -f $tmp
		    ./cleanup -l $log -r "\"make context\" failed in Workload" -a
		    exit 1
		fi
		for dir in `sed 's/ .*//' Tmp/workload`
		do
			rm -rf $dir
			mkdir $dir
			cp Workload/* $dir
		done
		echo "done."
		echo "" >>$log
		echo "Output sent to ... $ttys" >>$log
		echo "Directories for temporary files ... $dirs" >>$log
		echo "" >>$log
		/etc/df >>$log
		echo "" >>$log
		if test $test = work
		then
		    ./iamalive '60 second wallclock accuracy check ...'
		    echo "SIGALRM check: " `./clock` >>$log
		    echo "done."
		fi
		echo "This test generates lots of tty output"
		;;

	*)	./cleanup -l $log -r "run: unknown test \"$test\"" -a
		exit 1
		;;
    esac
    for file in $need
    do
	if make $need >/dev/null 2>$tmp
	then
	    :
	else
	    cat $tmp
	    cat $tmp >>$log
	    rm -f $tmp
	    ./cleanup -l $log -r "\"make $need\" failed!" -a
	    exit 1
	fi
    done
    echo "$logmsg" >>$log
    for param in $paramlist
    do
	param=`echo $param | sed 's/_/ /g'`
	./iamalive "   [$param] -"
	eval msg='"'$parammsg'"'
	eval opt='"'$options'"'
	if test "$msg" != ""
	then
	    echo "" >>$log
	    echo "$msg" >>$log
	fi
	rm -f $tmp
	for i in $repeat
	do
	    trap "./cleanup -l $log -i $i $cleanopt -a; exit" 1 2 3 15
	    ./iamalive $i
	    if test "$stdin" = ""
	    then
		time $prog $opt 2>>$tmp >>$stdout
	    else
		time $prog $opt <$stdin 2>>$tmp >>$stdout
	    fi
	    status=$?
	    if test $status != 0
	    then
		if test -f $tmp
		then
		    cp $tmp Tmp/save.$test.$param
		    ./cleanup -l $log -i $i $cleanopt -r "run: test=$test param=$param fatalstatus=$status" -a
		else
		    ./cleanup -l $log -r "run: test=$test param=$param fatalstatus=$status" -a
		fi
		exit
	    fi
	    test $prog = makework && ./cleanup -w
	done
	./cleanup -l $log $cleanopt
    done
    case $test
    in
	C)
	    rm -f cctest.o a.out
	    ;;
	work|x)
	    echo "Check for corpses ... " >>$logwork
	    if test "`echo Tmp/*.tmp`" != 'Tmp/*.tmp'
	    then
		echo "Unclaimed temporary workfiles?" >>$logwork
		ls -l Tmp/*.tmp >>$logwork
	    fi
	    ( cd Workload ; ls ) >/tmp/work$$
	    for dir in `sed 's/ .*//' Tmp/workload`
	    do
		( cd $dir ; ls ) >/tmp/user$$
		comm -23 /tmp/work$$ /tmp/user$$ >/tmp/x$$
		if test -s /tmp/x$$
		then
		    echo "Files missing from $dir ..." >>$logwork
		    echo "   " `cat /tmp/x$$` >>$logwork
		fi
		comm -13 /tmp/work$$ /tmp/user$$ >/tmp/x$$
		if test -s /tmp/x$$
		then
		    echo "Extra files in $dir ..." >>$logwork
		    echo "   " `cat /tmp/x$$` >>$logwork
		fi
		rm -rf $dir
	    done
	    rm -f /tmp/*$$
	    ;;
    esac
    echo ""
done
echo "" >>$log
echo " " `who | wc -l` "interactive users." >>$log
echo "End Benchmark Run ($date) ...." >>$log
echo "End Benchmark Run ($date) ...."
exit
