#!/bin/bash

###SHELLPACK preamble highalloc-bench 0
. $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

###SHELLPACK parseargBegin
###SHELLPACK parseargParam --mb-per-sec MB_PER_SEC
###SHELLPACK parseargParam --percent    HIGHALLOC_PERCENT
###SHELLPACK parseargParam --workloads  WORKLOADS
###SHELLPACK parseargParam --gfp-flags  HIGHALLOC_GFPFLAGS
###SHELLPACK parseargEnd

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

###SHELLPACK init_complete

# 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
