#!/bin/bash
# This is the script to the kernbench benchmark.
#
# reqparam value The number of threads to compile with (the option to make's -j)
# reqparam value The number of iterations to run.
# optparam prefix "-k" value type location: Where type and location can be passed directly into the get_kernel function in functions
# optparam prefix "-c" value A URL to the config file to use
#

. /etc/autobench.conf || . functions

function print_usage() {
  echo "$0 threads iterations [-k kernel] [-c config_url]"
  echo -e "\tThreads is the number of threads to compile with (make gets -jthreads)"
  echo -e "\tIterations is the number of times to do the compile"
  echo -e "\tKernel is:"
  echo -e "\t\ttype location: Where type and location can be passed directly"
  echo -e "\t\tinto the get_kernel function in functions"
  echo -e "\tConfig_URL is the URL of the config file to use"
  exit 1
}

# Process the arguments ######################################################
if [ $# -lt 2 ]; then
  print_usage
fi

THREADS=$1
if [ $THREADS -eq 0 ]; then
  THREADS=""
fi
  
ITERATIONS=$2
shift 2

# Defaults
KERNEL="stock 2.4.17"
CONFIG_URL="$AUTODIR/sources/kernbench/config"

while [ $# -gt 1 ]; do
  if [ "$1" = "-k" ]; then
    shift
    KERNEL=""
    while [ $# -gt 0 -a "$1" != "-c" ]; do
      KERNEL="$KERNEL $1"
      shift
    done
  elif [ "$1" = "-c" ]; then
    CONFIG_URL=$2
    shift 2
  else
    shift
  fi
done

# Install support files ######################################################
if [ ! \( -e $AUTODIR/sources/kernbench \) ]; then
  $AUTODIR/scripts/benchmarks/install/kernbench || exit 2
fi

getcommand doprofilers
doprofilers install

# Prepare the benchmark ######################################################
case `uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ \
      -e s/sa110/arm/` in
  i386)   
          true # Don't need to do anything here
          ;;
  *)
          # Unless we say otherwise, we'll have to cross compile.
	  TARGET_ARCH=i386
          MAKE_OPTS="CROSS_COMPILE=$TARGET_ARCH-linux- ARCH=$TARGET_ARCH"
          PATH=$AUTODIR/sources/xgcc-$TARGET_ARCH/bin:$PATH
          ;;
esac

echo KERNBENCH ... putting results into $LOGDIR
get_kernel $TMPDIR/kernbench $KERNEL
check_status "Getting and unpacking the kernel..."

pushd $TMPDIR/kernbench > /dev/null
make $MAKE_OPTS mrproper
echo .... make $MAKE_OPTS oldconfig
get_file_as .config $CONFIG_URL

yes "" | make $MAKE_OPTS oldconfig >/dev/null
make $MAKE_OPTS clean >/dev/null
make $MAKE_OPTS -j$THREADS dep >/dev/null 2>&1
tar cf /dev/null .
echo .... KERNBENCH warming up
make $MAKE_OPTS -j$THREADS vmlinux > /dev/null 2>&1
make $MAKE_OPTS clean >/dev/null


# Run the benchmark ##########################################################
for ((i=1; i<=$ITERATIONS; i++)); do
	echo .... KERNBENCH pass $i
	sync
	echo .... make $MAKE_OPTS -j$THREADS vmlinux
	cat /proc/slabinfo > $LOGDIR/benchmark/slabinfo.pre.$i

	$TIME_CMD make $MAKE_OPTS -j$THREADS vmlinux 2>> $LOGDIR/benchmark/time.$i > /dev/null

	cat /proc/slabinfo > $LOGDIR/benchmark/slabinfo.post.$i
	make $MAKE_OPTS clean >/dev/null
done

# Run the benchmark with profiling ###########################################
echo .... KERNBENCH pass $i
sync
echo .... make $MAKE_OPTS -j$THREADS vmlinux
startprofilers

$TIME_CMD make $MAKE_OPTS -j$THREADS vmlinux 2>> $LOGDIR/benchmark/time.profile > /dev/null

stopprofilers
doprofilers report

make $MAKE_OPTS clean >/dev/null

# Postprocess the results ####################################################
for ((i=1; i<=$ITERATIONS; i++)); do
	grep elapsed $LOGDIR/benchmark/time.$i
	grep elapsed $LOGDIR/benchmark/time.$i >> $LOGDIR/benchmark/time
done

doprofilers postprocess

pushd $LOGDIR/benchmark > /dev/null
$AUTODIR/sources/kernbench/avgtime . > $LOGDIR/benchmark/avgtime
popd > /dev/null


# clean up the tree to save space
rm -rf $TMPDIR/kernbench
popd > /dev/null
