#!/bin/bash
P=pagealloc-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
ORDER_MIN=0
ORDER_MAX=4
GFPFLAGS=GFP_KERNEL
BATCH_MIN=1
BATCH_SIZE=$((128*1048576))

# 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
		;;
	--min-order)
		ORDER_MIN=$2
		shift 2
		;;
	--max-order)
		ORDER_MAX=$2
		shift 2
		;;
	--gfp-flags)
		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

# Include monitor hooks
. $SHELLPACK_INCLUDE/include-monitor.sh

install-depends cpupower
cpupower frequency-set -g performance

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

stap -e 'probe begin { println("validate systemtap") exit () }' || exit $SHELLPACK_SUCCESS

echo -n > $LOGDIR_RESULTS/pagealloc.log
for ORDER in `seq $ORDER_MIN $ORDER_MAX`; do
	BATCH_MAX=$((((BATCH_SIZE) / 4096) >> $ORDER))
	BATCH=$BATCH_MIN

	while [ $BATCH -lt $BATCH_MAX ]; do
		# Setup the stap script
		cat $SHELLPACK_STAP/pagealloc-micro.stp | sed \
        		-e "s/define PARAM_GFPFLAGS.*/define PARAM_GFPFLAGS $GFPFLAGS/" \
        		-e "s/define PARAM_BATCH.*/define PARAM_BATCH $BATCH/" \
        		-e "s/define PARAM_ORDER.*/define PARAM_ORDER $ORDER/" > /tmp/pagealloc.stp

		# Execute
		stap -DSTAP_OVERRIDE_STUCK_CONTEXT -g /tmp/pagealloc.stp &
		STAP_PID=$!

		ATTEMPT=0
		echo -n Waiting for module to load
		sleep 1
		while [ ! -e /proc/mmtests-pagealloc-micro ]; do
			echo -n .
			sleep 1
			ATTEMPT=$((ATTEMPT+1))
			if [ $ATTEMPT = 180 ]; then
				die Failed to run stap module after 3 minutes
			fi
		done
		echo
		echo Executing test

		monitor_pre_hook $LOGDIR_RESULTS $ORDER-$BATCH
		cat /proc/mmtests-pagealloc-micro | tee -a $LOGDIR_RESULTS/pagealloc.log
		monitor_post_hook $LOGDIR_RESULTS $ORDER-$BATCH

		ATTEMPT=0
		echo -n Waiting for module to unload
		kill -INT $STAP_PID
		sleep 2
		while [ -e /proc/mmtests-pagealloc-micro ]; do
			kill -INT $STAP_PID
			echo -n .
			sleep 1
			ATTEMPT=$((ATTEMPT+1))
			if [ $ATTEMPT = 180 ]; then
				die Failed to unload stap module after 3 minutes
			fi
		done
		echo

		BATCH=$((BATCH<<1))
	done
done

# Split out results a bit for easier reporting later
IFS="
"
rm $LOGDIR_RESULTS/alloc-* 2> /dev/null
rm $LOGDIR_RESULTS/free-* 2> /dev/null

for LINE in `cat $LOGDIR_RESULTS/pagealloc.log`; do
	ORDER=`echo $LINE | awk '{print $2}'`
	BATCH=`echo $LINE | awk '{print $4}'`
	ALLOC=`echo $LINE | awk '{print $6}'`
	FREE=`echo $LINE | awk '{print $8}'`

	echo "$BATCH $ALLOC" >> $LOGDIR_RESULTS/alloc-$ORDER
	echo "$BATCH $FREE"  >> $LOGDIR_RESULTS/free-$ORDER
done

exit $SHELLPACK_SUCCESS
#### Description Micro-benchmark to stress the page allocator
#### Details pagealloc-bench 32
