#!/bin/bash
# Run tlbflush benchmark

P=tlbflush-bench
DEFAULT_VERSION=0
. $SHELLPACK_INCLUDE/common.sh
TIME_CMD=`which time`
if [ "$TIME_CMD" = "" ]; then
        TIMEFORMAT="%2Uuser %2Ssystem %Relapsed %P%%CPU"
        TIME_CMD="time"
fi

TLBFLUSH_MAX_THREADS=8
TLBFLUSH_MAX_ENTRIES=512
TLBFLUSH_ITERATIONS=200

# Basic argument parser
TASKSET_SERVER=
TASKSET_CLIENT=
SERVERSIDE_COMMAND=none
SERVERSIDE_NAME=`date +%Y%m%d-%H%M-%S`

while [ "$1" != "" ]; do
	case "$1" in
	-v)
		VERSION=$2
		shift 2
		;;
	--serverside-command)
		SERVERSIDE_COMMAND=$2
		shift 2
		;;
	--serverside-name)
		SERVERSIDE_NAME=$2
		shift 2
		;;
	--install-only)
		INSTALL_ONLY=yes
		shift
		;;
	--install-force)
		INSTALL_FORCE=yes
		shift
		;;
	--max-threads)
		TLBFLUSH_MAX_THREADS=$2
		shift 2
		;;
	--max-entries)
		TLBFLUSH_MAX_ENTRIES=$2
		shift 2
		;;
	--iterations)
		TLBFLUSH_ITERATIONS=$2
		shift 2
		;;
	*)
		echo Unrecognised option: $1
		shift
	esac
done
if [ "$TASKSET_SERVER" != "" ]; then
	echo TASKSET_SERVER: $TASKSET_SERVER
	echo TASKSET_CLIENT: $TASKSET_CLIENT
fi
if [ -z "$VERSION" ]; then
	VERSION=$DEFAULT_VERSION
fi

if [ "$INSTALL_FORCE" = "yes" ]; then
	rm -rf $SHELLPACK_SOURCES/tlbflush-${VERSION}
fi
if [ ! -d $SHELLPACK_SOURCES/tlbflush-${VERSION}-installed ]; then
	mmtests_activity source-install
	$SHELLPACK_INCLUDE/shellpack-install-tlbflush -v ${VERSION}  || die tlbflush install script returned error
	mmtests_activity source-installed
fi
cd $SHELLPACK_SOURCES/tlbflush-${VERSION}-installed || die Failed to cd to tlbflush install directory
if [ "$INSTALL_ONLY" = "yes" ]; then
	echo tlbflush installed only as requested.
	exit $SHELLPACK_SUCCESS
fi
# Include monitor hooks
. $SHELLPACK_INCLUDE/include-monitor.sh

EXIT_CODE=$SHELLPACK_SUCCESS

NR_THREADS=1
LAST_NR_THREADS=0
while [ $NR_THREADS -lt $TLBFLUSH_MAX_THREADS ]; do
	TMP_NR_THREADS=$LAST_NR_THREADS
	LAST_NR_THREADS=$NR_THREADS
	NR_THREADS=$((NR_THREADS+TMP_NR_THREADS))
	if [ $NR_THREADS -lt 1 ]; then
		continue
	fi
	if [ $NR_THREADS -gt $TLBFLUSH_MAX_THREADS ]; then
		NR_THREADS=$TLBFLUSH_MAX_THREADS
	fi
	mmtests_activity process $NR_THREADS/$TLBFLUSH_MAX_THREADS
monitor_pre_hook $LOGDIR_RESULTS $NR_THREADS

mmtests_activity threads-$NR_THREADS

NR_ENTRIES=$((RANDOM%TLBFLUSH_MAX_ENTRIES))
for ITERATION in `seq 1 $TLBFLUSH_ITERATIONS`; do
	mmtests_activity iteration $ITERATION
	THIS_MAX_ENTRIES=$TLBFLUSH_MAX_ENTRIES
	
	# Select a range of entries to randomly select from. This is to ensure
	# an evenish spread of entries to be tested
	NR_SECTION=$((ITERATION%8))
	RANGE=$((TLBFLUSH_MAX_ENTRIES/8))
	THIS_MIN_ENTRIES=$((RANGE*NR_SECTION+1))
	THIS_MAX_ENTRIES=$((THIS_MIN_ENTRIES+RANGE))

	NR_ENTRIES=$((THIS_MIN_ENTRIES+(RANDOM%RANGE)))
	if [ $NR_ENTRIES -gt $THIS_MAX_ENTRIES ]; then
		NR_ENTRIES=$THIS_MAX_ENTRIES
	fi
	
	if [ $((ITERATION%10)) -eq 0 ]; then
		echo Iteration:$ITERATION Threads:$NR_THREADS/$TLBFLUSH_MAX_THREADS
	fi

	RESULT=`$SHELLPACK_SOURCES/tlbflush-${VERSION}-installed/tlbflush -n $NR_ENTRIES -t $NR_THREADS 2>&1`
	RETVAL=$?
	if [ $RETVAL -ne 0 ]; then
		error tlbflush returned non-zero value with $NR_THREADS
		exit $SHELLPACK_ERROR
	fi
	echo $RESULT nr_entries $NR_ENTRIES | tee -a $LOGDIR_RESULTS/tlbflush-$NR_THREADS.log
	sync
done

monitor_post_hook $LOGDIR_RESULTS $NR_THREADS
done

exit $EXIT_CODE
#### Description Alex Shis tlb range flush benchmark
#### Details tlbflush-bench 32
