#!/bin/sh
# - nr_instances
# - cpu_node_bind
# - mem_node_bind

. $LKP_SRC/lib/reproduce-log.sh
. $LKP_SRC/lib/numactl.sh

## wrapper to run other other tests

program=$1
program_dir=$(dirname $0)

# Prefer to OOM kill job runner first.
# This prevents some server/client test cases from blocking on OOM.
echo 1000 > /proc/$PPID/oom_score_adj

echo $$ >> $TMP/pid-tests

shift

fifo=$TMP/fifo-$program
[ -p "$fifo" ] || mkfifo $fifo
tee -a $TMP_RESULT_ROOT/$program < $fifo &
echo $! >> $TMP/.pid-pipes

# in particular, avoid time in trinity
[ -n "$category" ] && {
	time_path=$(which time)
	if [ "x${time_path}" != "x" ];then
		time_help=$(${time_path} --help 2>/dev/null)
		[ "${time_help#*--output}" != "${time_help}" ] &&
			time_prefix="${time_path} -v -o $TMP/${program}.time"
	fi
}

setup_cgroup()
{
	[ -z "$1" ] && return
	[ "$1" = 'nocg' ] && return
	[ -n $CGROUP_MNT ] || return

	if [ "$cgroup_ver" = 1 ]; then
		local subsys_tasks
		for subsys_tasks in $CGROUP_MNT/*/$1/tasks
		do
			log_eval "echo \$\$ > '$subsys_tasks'"
		done
	elif [ "$cgroup_ver" = 2 ]; then
		log_eval "echo \$\$ > $CGROUP_MNT/$1/cgroup.procs"
	fi
}

export testcase=${testcase#kvm:}
if [ -n "$nr_instances" ]; then
	: "${cgroups:=nocg}"
	parse_numa_node_binding "$cpu_node_bind" "$mem_node_bind"

	rm -rf $TMP_RESULT_ROOT/log-$program
	mkdir -p $TMP_RESULT_ROOT/log-$program
	(
	oexec_prefix=$exec_prefix
	i=1
	while [ "$i" -le "$nr_instances" ]; do
		for cg in $cgroups; do
			export instance_id=$i
			export instance_cgroup=$cg
			setup_cgroup "$cg"
			numa_bind=$(numa_node_binding "$i")
			[ -n "$numa_bind" ] && exec_prefix="$oexec_prefix $numa_bind"
			$time_prefix $exec_prefix $program_dir/$program "$@" > "$TMP_RESULT_ROOT/log-$program/$i" &
			i=$((i+1))
			[ "$i" -gt "$nr_instances" ] && break
		done
	done
	wait
	cd $TMP_RESULT_ROOT/log-$program && ls | sort -h | xargs cat > $fifo
	)
	rm -rf $TMP_RESULT_ROOT/log-$program
else
	exec $time_prefix $exec_prefix $program_dir/$program "$@" > $fifo
fi
