18c2ecf20Sopenharmony_ci#!/bin/bash
28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0+
38c2ecf20Sopenharmony_ci#
48c2ecf20Sopenharmony_ci# Alternate sleeping and spinning on randomly selected CPUs.  The purpose
58c2ecf20Sopenharmony_ci# of this script is to inflict random OS jitter on a concurrently running
68c2ecf20Sopenharmony_ci# test.
78c2ecf20Sopenharmony_ci#
88c2ecf20Sopenharmony_ci# Usage: jitter.sh me duration [ sleepmax [ spinmax ] ]
98c2ecf20Sopenharmony_ci#
108c2ecf20Sopenharmony_ci# me: Random-number-generator seed salt.
118c2ecf20Sopenharmony_ci# duration: Time to run in seconds.
128c2ecf20Sopenharmony_ci# sleepmax: Maximum microseconds to sleep, defaults to one second.
138c2ecf20Sopenharmony_ci# spinmax: Maximum microseconds to spin, defaults to one millisecond.
148c2ecf20Sopenharmony_ci#
158c2ecf20Sopenharmony_ci# Copyright (C) IBM Corporation, 2016
168c2ecf20Sopenharmony_ci#
178c2ecf20Sopenharmony_ci# Authors: Paul E. McKenney <paulmck@linux.ibm.com>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cime=$(($1 * 1000))
208c2ecf20Sopenharmony_ciduration=$2
218c2ecf20Sopenharmony_cisleepmax=${3-1000000}
228c2ecf20Sopenharmony_cispinmax=${4-1000}
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_cin=1
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_cistarttime=`gawk 'BEGIN { print systime(); }' < /dev/null`
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cinohotplugcpus=
298c2ecf20Sopenharmony_cifor i in /sys/devices/system/cpu/cpu[0-9]*
308c2ecf20Sopenharmony_cido
318c2ecf20Sopenharmony_ci	if test -f $i/online
328c2ecf20Sopenharmony_ci	then
338c2ecf20Sopenharmony_ci		:
348c2ecf20Sopenharmony_ci	else
358c2ecf20Sopenharmony_ci		curcpu=`echo $i | sed -e 's/^[^0-9]*//'`
368c2ecf20Sopenharmony_ci		nohotplugcpus="$nohotplugcpus $curcpu"
378c2ecf20Sopenharmony_ci	fi
388c2ecf20Sopenharmony_cidone
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ciwhile :
418c2ecf20Sopenharmony_cido
428c2ecf20Sopenharmony_ci	# Check for done.
438c2ecf20Sopenharmony_ci	t=`gawk -v s=$starttime 'BEGIN { print systime() - s; }' < /dev/null`
448c2ecf20Sopenharmony_ci	if test "$t" -gt "$duration"
458c2ecf20Sopenharmony_ci	then
468c2ecf20Sopenharmony_ci		exit 0;
478c2ecf20Sopenharmony_ci	fi
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	# Check for stop request.
508c2ecf20Sopenharmony_ci	if test -f "$TORTURE_STOPFILE"
518c2ecf20Sopenharmony_ci	then
528c2ecf20Sopenharmony_ci		exit 1;
538c2ecf20Sopenharmony_ci	fi
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	# Set affinity to randomly selected online CPU
568c2ecf20Sopenharmony_ci	if cpus=`grep 1 /sys/devices/system/cpu/*/online 2>&1 |
578c2ecf20Sopenharmony_ci		 sed -e 's,/[^/]*$,,' -e 's/^[^0-9]*//'`
588c2ecf20Sopenharmony_ci	then
598c2ecf20Sopenharmony_ci		:
608c2ecf20Sopenharmony_ci	else
618c2ecf20Sopenharmony_ci		cpus=
628c2ecf20Sopenharmony_ci	fi
638c2ecf20Sopenharmony_ci	# Do not leave out non-hot-pluggable CPUs
648c2ecf20Sopenharmony_ci	cpus="$cpus $nohotplugcpus"
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	cpumask=`awk -v cpus="$cpus" -v me=$me -v n=$n 'BEGIN {
678c2ecf20Sopenharmony_ci		srand(n + me + systime());
688c2ecf20Sopenharmony_ci		ncpus = split(cpus, ca);
698c2ecf20Sopenharmony_ci		curcpu = ca[int(rand() * ncpus + 1)];
708c2ecf20Sopenharmony_ci		mask = lshift(1, curcpu);
718c2ecf20Sopenharmony_ci		if (mask + 0 <= 0)
728c2ecf20Sopenharmony_ci			mask = 1;
738c2ecf20Sopenharmony_ci		printf("%#x\n", mask);
748c2ecf20Sopenharmony_ci	}' < /dev/null`
758c2ecf20Sopenharmony_ci	n=$(($n+1))
768c2ecf20Sopenharmony_ci	if ! taskset -p $cpumask $$ > /dev/null 2>&1
778c2ecf20Sopenharmony_ci	then
788c2ecf20Sopenharmony_ci		echo taskset failure: '"taskset -p ' $cpumask $$ '"'
798c2ecf20Sopenharmony_ci		exit 1
808c2ecf20Sopenharmony_ci	fi
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	# Sleep a random duration
838c2ecf20Sopenharmony_ci	sleeptime=`awk -v me=$me -v n=$n -v sleepmax=$sleepmax 'BEGIN {
848c2ecf20Sopenharmony_ci		srand(n + me + systime());
858c2ecf20Sopenharmony_ci		printf("%06d", int(rand() * sleepmax));
868c2ecf20Sopenharmony_ci	}' < /dev/null`
878c2ecf20Sopenharmony_ci	n=$(($n+1))
888c2ecf20Sopenharmony_ci	sleep .$sleeptime
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	# Spin a random duration
918c2ecf20Sopenharmony_ci	limit=`awk -v me=$me -v n=$n -v spinmax=$spinmax 'BEGIN {
928c2ecf20Sopenharmony_ci		srand(n + me + systime());
938c2ecf20Sopenharmony_ci		printf("%06d", int(rand() * spinmax));
948c2ecf20Sopenharmony_ci	}' < /dev/null`
958c2ecf20Sopenharmony_ci	n=$(($n+1))
968c2ecf20Sopenharmony_ci	for i in {1..$limit}
978c2ecf20Sopenharmony_ci	do
988c2ecf20Sopenharmony_ci		echo > /dev/null
998c2ecf20Sopenharmony_ci	done
1008c2ecf20Sopenharmony_cidone
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ciexit 1
103