#!/bin/bash

P=highalloc-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
. $SHELLPACK_INCLUDE/include-hugepage.sh
. $SHELLPACK_INCLUDE/include-sizes.sh

getpagesize             # Sets PAGESIZE
gethugepagesize         # Sets HUGE_PAGESIZE
gethugetlb_order        # Sets HUGETLB_ORDER
getmemtotals            # Sets MEMTOTAL_BYTES and MEMTOTAL_PAGES
HIGHALLOC_ORDER=$HUGETLB_ORDER
HIGHALLOC_COUNT=0
HIGHALLOC_GFPFLAGS=GFP_ALLOC_LIKE_HUGETLB

# 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
		;;
	--mb-per-sec)
		MB_PER_SEC=$2
		shift 2
		;;
	--percent)
		HIGHALLOC_PERCENT=$2
		shift 2
		;;
	--workloads)
		WORKLOADS=$2
		shift 2
		;;
	--gfp-flags)
		HIGHALLOC_GFPFLAGS=$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

# Systemtap required
if [ "`which stap`" = "" ]; then
	echo systemtap is required
	exit -1
fi

# Calculate number of huge pages to allocate
if [ "$HIGHALLOC_COUNT" = "0" ]; then
	echo -n "Discovering number of pages to allocate: "
	HIGHALLOC_COUNT=$(($MEMTOTAL_BYTES/$HUGE_PAGESIZE))
	if [ "$HIGHALLOC_PERCENT" != "" ]; then
  		HIGHALLOC_COUNT=$(($HIGHALLOC_COUNT*$HIGHALLOC_PERCENT/100))
	fi
	echo $HIGHALLOC_COUNT
fi

# Work out how long to stall between allocation requests
if [ "$MB_PER_SEC" != "" ]; then
	MB_PER_SEC_INT=`printf "%d" "$MB_PER_SEC"`
	if [ "$MB_PER_SEC" != "$MB_PER_SEC" ]; then
		echo Megabytes per second must be specified as an integer
		exit -1
	fi
	if [ $MB_PER_SEC -le 0 ]; then
		MB_PER_SEC=1
	fi

	# Adjust the MS delay accordingly
	BYTES_PER_MS=$(($MB_PER_SEC*1048576/1000))
	ALLOC_PAGESIZE=$(($PAGESIZE*(1<<$HIGHALLOC_ORDER)))
	MS_DELAY=$(($ALLOC_PAGESIZE/$BYTES_PER_MS))
	echo Adjusted ms_delay to $MS_DELAY for $MB_PER_SEC megabytes per second IO queues
fi

# Configure the stap script
cat $SHELLPACK_STAP/highalloc.stp | sed \
        -e "s/define PARAM_MSDELAY.*/define PARAM_MSDELAY $MS_DELAY/" \
        -e "s/define PARAM_ALLOCS.*/define PARAM_ALLOCS $HIGHALLOC_COUNT/" \
	-e "s/define PARAM_GFPFLAGS.*/define PARAM_GFPFLAGS $HIGHALLOC_GFPFLAGS/" \
        -e "s/define PARAM_ORDER.*/define PARAM_ORDER $HUGETLB_ORDER/" > /tmp/highalloc.stp

# Cycle through each of the requested workloads
for WORKLOAD in $WORKLOADS; do

	cd $SHELLPACK_TOPLEVEL
	mkdir -p $LOGDIR_RESULTS
	echo Starting background workload: $WORKLOAD
	./bin/run-single-test.sh $WORKLOAD > $LOGDIR_RESULTS/workload-$WORKLOAD.log 2>&1 &
	WORKLOAD_PID=$!
	
	# While workload is running, try highalloc tests
	STATUS=0
	PASS=1
	while [ $STATUS -eq 0 ]; do
		echo Background workload: $WORKLOAD pid $WORKLOAD_PID, highalloc pass $PASS
		STARTTIME=`date +%s`
		stap -g /tmp/highalloc.stp > $LOGDIR_RESULTS/highalloc-$WORKLOAD-$PASS.log 2>&1
		ENDTIME=`date +%s`
		SUCCESSRATE=`grep "% Success" $LOGDIR_RESULTS/highalloc-$WORKLOAD-$PASS.log | awk '{print $3}'`
		echo $PASS $SUCCESSRATE $((ENDTIME-STARTTIME)) >> $LOGDIR_RESULTS/workload-$WORKLOAD-results.log
		echo Pass complete: `date`
		PASS=$((PASS+1))

		sleep 10
		ps -p $WORKLOAD_PID > /dev/null
		STATUS=$?
	done
	rm -rf $SHELLPACK_LOG/$WORKLOAD
	rm -rf $SHELLPACK_TEMP/*
done

echo Running allocation test at rest
sync
echo 3 > /proc/sys/vm/drop_caches
stap -g /tmp/highalloc.stp | tee $LOGDIR_RESULTS/highalloc-at-end.log

rm -rf $SHELLPACK_TEMP
exit $SHELLPACK_SUCCESS
#### Description Run a highorder allocation test in the background of any test
#### Details highalloc-bench 25
