#!/bin/bash

# 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$

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

echo PATH = $PATH
echo lat_syscall = `readlink -f lat_syscall`

# lat_unix, lat_udp, lat_tcp only do one run!!!
# we loop to repeat the tests
N_RUNS=6

if [ -f $1 ]
then	. $1
	echo Using config in $1 >> ${OUTPUT}
else	echo Using defaults >> ${OUTPUT}
	ENOUGH=1000000
	TIMING_O=0
	LOOP_O=0
fi
export ENOUGH TIMING_O LOOP_O

if [ X$FILE = X ]
then	FILE=/tmp/XXX
	touch $FILE || echo Can not create $FILE >> ${OUTPUT}
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=/tmp/lat_fs
fi
MP=N

# Figure out as much stuff as we can about this system.
# Sure would be nice if everyone had SGI's "hinv".
echo \[lmbench2.0 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 \[NETrunS: ${NETrunS}] 1>&2
echo \[PROCESSORS: ${PROCESSORS}] 1>&2
echo \[REMOTE: ${REMOTE}] 1>&2
echo \[SLOWFS: ${SLOWFS}] 1>&2
echo \[OS: ${OS}] 1>&2
echo \[TIMING_O: ${TIMING_O}] 1>&2
echo \[LMBENCH VERSION: ${VERSION}] 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
#if 0
echo \[`date`] 1>&2
echo \[`uptime`] 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

STAT=$FSDIR/lmbench
mkdir $FSDIR 2>/dev/null
touch $STAT 2>/dev/null
if [ ! -f $STAT ]
then	echo "Can't make a file - $STAT - in $FSDIR" >> ${OUTPUT}
	touch $STAT
	exit 1
fi

function run {
	echo "$@"
	TMPOUT=/tmp/OUT
	rm -rf $TMPOUT
	$LOADER "$@" 2>>$TMPOUT | tee -a $TMPOUT
	cat $TMPOUT 1>&2
}

date >> ${OUTPUT}
echo Latency measurements >> ${OUTPUT}
msleep 250
run lat_syscall null
run lat_syscall read
run lat_syscall write
run lat_syscall stat $STAT
run lat_syscall fstat $STAT
run lat_syscall open $STAT

#select file (500), select tcp (500)
run lat_select file 500
run lat_select tcp 500

#sig install, sig_overhead, prot. Fault
run lat_sig install
run lat_sig catch
run lat_sig prot lat_sig

#AF_UNIX
echo AF_UNIX socket latency >> ${OUTPUT}
for i in $(eval echo "{1..$N_RUNS}")
do	run lat_unix
done

#forks
cp hello /tmp/hello
for i in fork dfork vfork exec dforkexec shell
do	run lat_proc $i
done
rm -f /tmp/hello

for i in $(eval echo "{1..$N_RUNS}")
do	rm -f $FILE
	run lmdd label="File $FILE write bandwidth:" of=$FILE move=${MB}m fsync=1 print=3
done

#0,4,10KB create/delete
date >> ${OUTPUT}
	echo Calculating file system latency >> ${OUTPUT}
	echo '"File system latency' 1>&2
	run lat_fs $FSDIR
	echo "" 1>&2

date >> ${OUTPUT}
echo Local netruning >> ${OUTPUT}

echo UDP socket latency >> ${OUTPUT}
run lat_udp -s &
sleep 3
for i in $(eval echo "{1..$N_RUNS}")
do	run lat_udp 127.0.0.1
	sleep 1
done
run lat_udp -127.0.0.1
sleep 3

echo TCP socket latency >> ${OUTPUT}
run lat_tcp -s &
sleep 3
for i in $(eval echo "{1..$N_RUNS}")
do	run lat_tcp 127.0.0.1
	sleep 1
done
run lat_tcp -127.0.0.1
sleep 3

echo TCP connect latency >> ${OUTPUT}
run lat_connect -s &
sleep 3
run lat_connect 127.0.0.1
sleep 1
run lat_connect -127.0.0.1
sleep 3

echo TCP socket bandwidth >> ${OUTPUT}
run bw_tcp -s &
sleep 3
for i in $(eval echo "{1..$N_RUNS}")
do	run bw_tcp 127.0.0.1
	sleep 1
done
run bw_tcp -127.0.0.1
sleep 3

date >> ${OUTPUT}
echo Bandwidth measurements >> ${OUTPUT}

for i in $(eval echo "{1..$N_RUNS}")
do	run bw_unix
done

for i in $(eval echo "{1..$N_RUNS}")
do	run bw_pipe
done

date >> ${OUTPUT}
msleep 250
echo Calculating context switch overhead >> ${OUTPUT}
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

## dep: This test is currently flaky; for the moment, let's comment it out for regression testing
#for size in $CTX
#do	for i in $(eval echo "{1..$N_RUNS}")
#	do	run lat_ctx -s $size $N
#	done
#done

date >> ${OUTPUT}
echo Calculating memory load latency >> ${OUTPUT}
msleep 250
echo "" 1>&2
echo "Memory load latency" 1>&2
if [ X$FASTMEM = XYES ]
then	run lat_mem_rd $MB 128
else	run lat_mem_rd $MB 16 32 64 128 256 512 1024 
fi
date >> ${OUTPUT}
echo '' 1>&2
echo \[`date`] 1>&2

date >> ${OUTPUT}
echo Calculating memory bandwidths >> ${OUTPUT}
msleep 250

echo "" 1>&2
echo \"read bandwidth 1>&2
for i in $ALL; do run bw_file_rd $i io_only $FILE; done
echo "" 1>&2

echo "" 1>&2
echo \"read open2close bandwidth 1>&2
for i in $ALL; do run bw_file_rd $i open2close $FILE; done
echo "" 1>&2

echo \"Mmap read bandwidth 1>&2
for i in $ALL; do run bw_mmap_rd $i mmap_only $FILE; done
echo "" 1>&2

echo \"Mmap read open2close bandwidth 1>&2
for i in $ALL; do run bw_mmap_rd $i open2close $FILE; done
echo "" 1>&2
rm -f $FILE

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

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

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

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

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

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

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

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

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

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

exit 0