#!/bin/sh

# lmbench - run the lmbench benchmark suite.
#
# Hacked by Larry McVoy (lm@sun.com, lm@sgi.com, lm@bitmover.com).
# Copyright (c) 1994 Larry McVoy.  GPLed software.
# $Id: s.lmbench 1.30 98/07/31 12:53:27-07:00 lm@lm.bitmover.com $

# Make sure we can find: ./cmd, df, and netstat
PATH=.:/usr/pkg/libexec/lmbench:$PATH:/etc:/usr/etc:/sbin:/usr/sbin
export PATH

if [ -f $1 ]
then	echo Using config in $1 > /dev/tty
	. $1
else	echo Using defaults > /dev/tty
	ENOUGH=1000000
	TIMING_O=0
	LOOP_O=0
fi
export ENOUGH TIMING_O LOOP_O SYNC_MAX SYNC_PID

if [ X$FILE = X ]
then	FILE=/tmp/XXX
	touch $FILE || echo Can not create $FILE
fi
if [ X$MB = X ]
then	MB=8
fi
AVAILKB=`expr $MB \* 1024`

# Figure out how big we can go for stuff that wants to use
# all and half of memory.
HALF="512 1k 2k 4k 8k 16k 32k 64k 128k 256k 512k 1m"
ALL="$HALF 2m"
i=4
while [ $i -le $MB ]
do
	ALL="$ALL ${i}m"
	h=`expr $i / 2`
	HALF="$HALF ${h}m"
	i=`expr $i \* 2`
done


if [ X$FSDIR = X ]
then	FSDIR=/usr/tmp/lat_fs
fi
MP=N
if [ $SYNC_MAX -gt 1 ]
then	if [ X$SYNC_PID = X ]
	then	echo "Must set both SYNC_MAX and SYNC_PID"
		exit 1
	fi
	if [ "X$DISKS" != X ]
	then	echo "MP and disks are mutually exclusive (sorry)"
		exit 1
	fi
	if [ "X$REMOTE" != X ]
	then	echo "MP and remote networking are mutually exclusive (sorry)"
		exit 1
	fi
	MP=Y
fi
if [ X`os` = Xhpux ]
then	RSH=remsh
else	RSH=rsh
fi

# Figure out as much stuff as we can about this system.
# Sure would be nice if everyone had SGI's "hinv".
echo \[lmbench1.1 results for `uname -a`] 1>&2
echo \[ALL: ${ALL}] 1>&2
echo \[DISKS: ${DISKS}] 1>&2
echo \[DISK_DESC: ${DISK_DESC}] 1>&2
echo \[ENOUGH: ${ENOUGH}] 1>&2
echo \[FAST: ${FAST}] 1>&2
echo \[FASTMEM: ${FASTMEM}] 1>&2
echo \[FILE: ${FILE}] 1>&2
echo \[FSDIR: ${FSDIR}] 1>&2
echo \[HALF: ${HALF}] 1>&2
echo \[INFO: ${INFO}] 1>&2
echo \[LOOP_O: ${LOOP_O}] 1>&2
echo \[MB: ${MB}] 1>&2
echo \[MHZ: ${MHZ}] 1>&2
echo \[MOTHERBOARD: ${MOTHERBOARD}] 1>&2
echo \[NETWORKS: ${NETWORKS}] 1>&2
echo \[PROCESSORS: ${PROCESSORS}] 1>&2
echo \[REMOTE: ${REMOTE}] 1>&2
echo \[SLOWFS: ${SLOWFS}] 1>&2
echo \[SYNC_MAX: ${SYNC_MAX}] 1>&2
echo \[SYNC_PID: ${SYNC_PID}] 1>&2
echo \[TIMING_O: ${TIMING_O}] 1>&2
echo \[LMBENCH VERSION: ${VERSION}] 1>&2
echo \[`date`] 1>&2
echo \[`uptime`] 1>&2
echo \[USER: $USER] 1>&2
echo \[HOSTNAME: `hostname`] 1>&2
echo \[NODENAME: `uname -n`] 1>&2
echo \[SYSNAME: `uname -s`] 1>&2
echo \[PROCESSOR: `uname -p`] 1>&2
echo \[MACHINE: `uname -m`] 1>&2
echo \[RELEASE: `uname -r`] 1>&2
echo \[VERSION: `uname -v`] 1>&2
netstat -i | while read i
do	echo \[net: "$i"] 1>&2
	set `echo $i`
	case $1 in
	    *ame)	;;
	    *)		ifconfig $1 | while read i
			do echo \[if: "$i"] 1>&2
			done
			;;
	esac
done

mount | while read i
do	echo \[mount: "$i"] 1>&2
done

if [ $MP = Y ]
then	SYNC=${FSDIR}/sync		# I want this to be global
	FSDIR=${FSDIR}/lmbench_${SYNC_PID}
	STAT=$FSDIR/lmbench.$SYNC_PID
	FILE=${FILE}.$SYNC_PID
else	STAT=$FSDIR/lmbench
fi
mkdir $FSDIR 2>/dev/null
touch $STAT 2>/dev/null
if [ ! -f $STAT ]
then	echo "Can't make a file in $FSDIR" > /dev/tty
	exit 1
fi
if [ X$SYNC != X ]
then	mkdir -p $SYNC 2>/dev/null
	if [ ! -d $SYNC ]
	then	echo "Can't make $SYNC"
		exit 1
	fi
	for i in bw_file_rd bw_mem bw_mmap_rd bw_pipe bw_tcp bw_unix \
	    lat_connect lat_ctx lat_fifo lat_fs lat_heap lat_http \
	    lat_mem_rd lat_mmap lat_pagefault lat_pipe lat_proc lat_rpc \
	    lat_select lat_sig lat_syscall lat_tcp lat_udp lat_unix \
	    lat_unix_connect lmdd lat_proc2 bw_file_rd2 bw_mmap_rd2 \
	    lat_ctx0_2 lat_ctx0_4 lat_ctx0_8 lat_ctx0_16 lat_ctx0_24 \
	    lat_ctx0_32 lat_ctx0_64 lat_ctx0_96 lat_ctx4_2 lat_ctx4_4 \
	    lat_ctx4_8 lat_ctx4_16 lat_ctx4_24 lat_ctx4_32 lat_ctx4_64 \
	    lat_ctx4_96 lat_ctx8_2 lat_ctx8_4 lat_ctx8_8 lat_ctx8_16 \
	    lat_ctx8_24 lat_ctx8_32 lat_ctx8_64 lat_ctx8_96 lat_ctx16_2 \
	    lat_ctx16_4 lat_ctx16_8 lat_ctx16_16 lat_ctx16_24 lat_ctx16_32 \
	    lat_ctx16_64 lat_ctx16_96 lat_ctx32_2 lat_ctx32_4 lat_ctx32_8 \
	    lat_ctx32_16 lat_ctx32_24 lat_ctx32_32 lat_ctx32_64 \
	    lat_ctx32_96 lat_ctx64_2 lat_ctx64_4 lat_ctx64_8 lat_ctx64_16 \
	    lat_ctx64_24 lat_ctx64_32 lat_ctx64_64 lat_ctx64_96 
	do	/bin/rm -rf $SYNC/$i
	done
fi

date > /dev/tty
echo Latency measurements > /dev/tty
if [ $MP = Y ]; then synchronize $SYNC/lat_syscall; fi
msleep 250
lat_syscall null
lat_syscall read
lat_syscall write
lat_syscall stat $STAT
lat_syscall fstat $STAT
lat_syscall open $STAT
if [ $MP = Y ]; then synchronize $SYNC/lat_select; fi
for i in 10 100 250 500
do	lat_select $i
done
if [ $MP = Y ]; then synchronize $SYNC/lat_sig; fi
lat_sig install
lat_sig catch
lat_sig prot lat_sig
if [ $MP = Y ]; then synchronize $SYNC/lat_pipe; fi
lat_pipe
if [ $MP = Y ]; then synchronize $SYNC/lat_unix; fi
lat_unix
if [ $MP = Y ]
then	if [ $SYNC_MAX = $SYNC_PID ]; then cp /usr/pkg/libexec/lmbench/hello /tmp/hello; fi
	synchronize $SYNC/lat_proc
else	cp /usr/pkg/libexec/lmbench/hello /tmp/hello
fi
lat_proc fork
lat_proc exec
lat_proc shell
if [ $MP = Y ]
then	synchronize $SYNC/lat_proc2
	if [ $SYNC_MAX = $SYNC_PID ]; then rm -f /tmp/hello; fi
else	rm /tmp/hello 
fi
rm -f $FILE
if [ $MP = Y ]; then synchronize $SYNC/lmdd; fi
lmdd label="File $FILE write bandwidth: " of=$FILE move=${MB}m fsync=1 print=3
if [ $MP = Y ]; then synchronize $SYNC/lat_pagefault; fi
lat_pagefault $FILE
if [ $MP = Y ]; then synchronize $SYNC/lat_mmap; fi
echo "" 1>&2
echo \"mappings 1>&2
for i in $ALL
do	lat_mmap $i $FILE
done
echo "" 1>&2
if [ X$SLOWFS != XYES ]
then	date > /dev/tty
	if [ $MP = Y ]; then synchronize $SYNC/lat_fs; fi
	echo Calculating file system latency > /dev/tty
	echo '"File system latency' 1>&2
	lat_fs $FSDIR
	echo "" 1>&2
fi

if [ X"$DISKS" != X ]
then	for i in $DISKS
	do	if [ -r $i ]
		then	echo "Calculating disk zone bw & seek times" > /dev/tty
			disk $i
			echo "" 1>&2
		fi
	done
fi

if [ $SYNC_PID = $SYNC_MAX ]
then	date > /dev/tty
	echo Local networking > /dev/tty
	if [ ! -d /usr/pkg/share/lmbench/webpage-lm ]
	then	(cd ../../src && tar xf webpage-lm.tar)
		sync
		sleep 1
	fi
	SERVERS="lat_udp lat_tcp lat_rpc lat_connect bw_tcp"
	for server in $SERVERS; do $server -s; done
	DOCROOT=/usr/pkg/share/lmbench/webpage-lm lmhttp 8008 &
	sleep 2;
	for i in localhost
	do
		lat_udp $i
		lat_udp -$i
		lat_tcp $i
		lat_tcp -$i
		lat_rpc $i;			 # Internal kill on this one.
		lat_connect $i
		lat_connect -$i
		bw_tcp $i
		bw_tcp -$i
		# I want a hot cache number
		lat_http $i 8008 < /usr/pkg/share/lmbench/webpage-lm/URLS > /dev/null 2>&1
		lat_http $i 8008 < /usr/pkg/share/lmbench/webpage-lm/URLS
		lat_http -$i 8008
	done

	for remote in $REMOTE 
	do	echo Networking to $remote > /dev/tty
		rcp $SERVERS lmhttp /usr/pkg/share/lmbench/webpage-lm.tar ${remote}:/tmp
		for server in $SERVERS
		do	$RSH $remote -n /tmp/$server -s &
		done
		$RSH $remote -n 'cd /tmp; tar xf webpage-lm.tar; cd webpage-lm; ../lmhttp 8008' &
		sleep 10
		echo "[ Networking remote to $remote: `$RSH $remote uname -a` ]" 1>&2
		lat_udp $remote; lat_udp -$remote;
		lat_tcp $remote; lat_tcp -$remote;
		lat_rpc $remote udp; lat_rpc $remote tcp; 
		lat_connect $remote; lat_connect -$remote;
		bw_tcp $remote; bw_tcp -$remote 
		# I want a hot cache number
		lat_http $remote 8008 < /usr/pkg/share/lmbench/webpage-lm/URLS > /dev/null 2>&1
		lat_http $remote 8008 < /usr/pkg/share/lmbench/webpage-lm/URLS
		lat_http -$remote 8008
		RM=
		for server in $SERVERS
		do	RM="/tmp/$server $RM"
		done
		$RSH $remote rm $RM
	done
fi	# MP

if [ $MP = Y ]; then synchronize $SYNC/bw_unix; fi
date > /dev/tty
echo Bandwidth measurements > /dev/tty
bw_unix
if [ $MP = Y ]; then synchronize $SYNC/bw_pipe; fi
bw_pipe
echo "" 1>&2
if [ $MP = Y ]; then synchronize $SYNC/bw_file_rd; fi
echo \"read bandwidth 1>&2
for i in $ALL
do	bw_file_rd $i io_only $FILE
done
echo "" 1>&2

echo "" 1>&2
if [ $MP = Y ]; then synchronize $SYNC/bw_file_rd2; fi
echo \"read open2close bandwidth 1>&2
for i in $ALL
do	bw_file_rd $i open2close $FILE
done
echo "" 1>&2

if [ $MP = Y ]; then synchronize $SYNC/bw_mmap_rd; fi
echo \"Mmap read bandwidth 1>&2
for i in $ALL
do	bw_mmap_rd $i mmap_only $FILE
done
echo "" 1>&2

if [ $MP = Y ]; then synchronize $SYNC/bw_mmap_rd2; fi
echo \"Mmap read open2close bandwidth 1>&2
for i in $ALL
do	bw_mmap_rd $i open2close $FILE
done
echo "" 1>&2
rm -f $FILE

if [ $MP = Y ]; then synchronize $SYNC/bw_mem; fi
echo \"libc bcopy unaligned 1>&2
for i in $HALF; do bw_mem $i bcopy; done; echo "" 1>&2

echo \"libc bcopy aligned 1>&2
for i in $HALF; do bw_mem $i bcopy conflict; done; echo "" 1>&2

echo \"unrolled bcopy unaligned 1>&2
for i in $HALF; do bw_mem $i fcp; done; echo "" 1>&2

echo \"unrolled partial bcopy unaligned 1>&2
for i in $HALF; do bw_mem $i cp; done; echo "" 1>&2

echo "Memory read bandwidth" 1>&2
for i in $ALL; do bw_mem $i frd; done; echo "" 1>&2

echo "Memory partial read bandwidth" 1>&2
for i in $ALL; do bw_mem $i rd; done; echo "" 1>&2

echo "Memory write bandwidth" 1>&2
for i in $ALL; do bw_mem $i fwr; done; echo "" 1>&2

echo "Memory partial write bandwidth" 1>&2
for i in $ALL; do bw_mem $i wr; done; echo "" 1>&2

echo "Memory partial read/write bandwidth" 1>&2
for i in $ALL; do bw_mem $i rdwr; done; echo "" 1>&2

echo "Memory bzero bandwidth" 1>&2
for i in $ALL; do bw_mem $i bzero; done; echo "" 1>&2

date > /dev/tty
msleep 250
if [ $MP = Y ]; then synchronize $SYNC/lat_ctx; fi
echo Calculating context switch overhead > /dev/tty
if [ $MB -ge 8 ]
then	CTX="0 4 8 16 32 64"
	N="2 4 8 16 24 32 64 96"
else
	CTX="0 4 8 16 32"
	N="2 4 8 16 24 32 64 96"
fi
	
for size in $CTX
do	if [ $MP = Y ]; then synchronize $SYNC/lat_ctx${size}_${N}; fi
	lat_ctx -s $size $N
done

date > /dev/tty
echo Calculating memory load latency > /dev/tty
msleep 250
echo "" 1>&2
if [ $MP = Y ]; then synchronize $SYNC/lat_mem_rd; fi
echo "Memory load latency" 1>&2
if [ X$FASTMEM = XYES ]
then	lat_mem_rd $MB 128
else	lat_mem_rd $MB 16 32 64 128 256 512 1024 
fi
date > /dev/tty
echo '' 1>&2
echo \[`date`] 1>&2

exit 0
