#!/bin/sh
# - runtime
# - nr_threads
# - mode
# - ipc
# - iterations
# - datasize

## Hackbench  is  both  a benchmark and a stress test for the Linux kernel scheduler.
## It's main job is to create a specified number  of  pairs  of schedulable entities
## (either threads or traditional processes) which communicate via either sockets or
## pipes and time how long it takes  for each pair to send data back and forth.

[ "$ipc" = 'pipe' ] && ipc_option='--pipe'

[ -n "$runtime" ] || runtime=600

# Default datasize for hackbench is 100
[ -n "$datasize" ] || datasize=100

set_env()
{
	# default 40 fds/group
	fds=40
	tasks=$((nr_threads * fds))

	# increase permitted open file number
	ulimit -n $((tasks + 2048))

	def_pid_max=32768
	[ "$tasks" -gt $((def_pid_max / 2)) ] && {
		sysctl -w kernel.pid_max=$((tasks * 2))
		sysctl -w kernel.threads-max=$((tasks * 2))
		sysctl -w vm.max_map_count=$((tasks * 100))
	}
}

set_loops()
{
	loops=$(( 30000 * nr_cpu / nr_threads ))
}

run_hackbench()
{
	# args: groups number, mode [process/thread], times
	local hackbench_path
	if [ -f /usr/bin/hackbench ]; then
		hackbench_path=/usr/bin/hackbench
	elif [ -f /lkp/benchmarks/hackbench/usr/local/bin/hackbench ]; then
		hackbench_path=/lkp/benchmarks/hackbench/usr/local/bin/hackbench
	else
		hackbench_path=/usr/local/bin/hackbench
	fi
	log_cmd $hackbench_path -g $nr_threads --$mode $ipc_option -l $loops -s $datasize
}

run_for_time()
{
	start_time=$(date +%s)
	while :
	do
		run_hackbench
		now=$(date +%s)
		[ $((now - start_time)) -gt "$runtime" ] && break
	done
}

run_for_iterations()
{
	for i in $(seq 1 $iterations); do
		echo "Iterations: $i"
		run_hackbench
	done
}

set_env
set_loops

if [ -n "$iterations" ]; then
	run_for_iterations
else
	run_for_time
fi
