Commit | Line | Data |
---|---|---|
6e524a60 PM |
1 | #!/bin/bash |
2 | # | |
3 | # Alternate sleeping and spinning on randomly selected CPUs. The purpose | |
4 | # of this script is to inflict random OS jitter on a concurrently running | |
5 | # test. | |
6 | # | |
7 | # Usage: jitter.sh me duration [ sleepmax [ spinmax ] ] | |
8 | # | |
9 | # me: Random-number-generator seed salt. | |
10 | # duration: Time to run in seconds. | |
11 | # sleepmax: Maximum microseconds to sleep, defaults to one second. | |
12 | # spinmax: Maximum microseconds to spin, defaults to one millisecond. | |
13 | # | |
14 | # This program is free software; you can redistribute it and/or modify | |
15 | # it under the terms of the GNU General Public License as published by | |
16 | # the Free Software Foundation; either version 2 of the License, or | |
17 | # (at your option) any later version. | |
18 | # | |
19 | # This program is distributed in the hope that it will be useful, | |
20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | # GNU General Public License for more details. | |
23 | # | |
24 | # You should have received a copy of the GNU General Public License | |
25 | # along with this program; if not, you can access it online at | |
26 | # http://www.gnu.org/licenses/gpl-2.0.html. | |
27 | # | |
28 | # Copyright (C) IBM Corporation, 2016 | |
29 | # | |
30 | # Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> | |
31 | ||
32 | me=$(($1 * 1000)) | |
33 | duration=$2 | |
34 | sleepmax=${3-1000000} | |
35 | spinmax=${4-1000} | |
36 | ||
37 | n=1 | |
38 | ||
39 | starttime=`awk 'BEGIN { print systime(); }' < /dev/null` | |
40 | ||
41 | while : | |
42 | do | |
43 | # Check for done. | |
44 | t=`awk -v s=$starttime 'BEGIN { print systime() - s; }' < /dev/null` | |
45 | if test "$t" -gt "$duration" | |
46 | then | |
47 | exit 0; | |
48 | fi | |
49 | ||
50 | # Set affinity to randomly selected CPU | |
51 | cpus=`ls /sys/devices/system/cpu/*/online | | |
52 | sed -e 's,/[^/]*$,,' -e 's/^[^0-9]*//' | | |
53 | grep -v '^0*$'` | |
54 | cpumask=`awk -v cpus="$cpus" -v me=$me -v n=$n 'BEGIN { | |
55 | srand(n + me + systime()); | |
56 | ncpus = split(cpus, ca); | |
57 | curcpu = ca[int(rand() * ncpus + 1)]; | |
58 | mask = lshift(1, curcpu); | |
59 | if (mask + 0 <= 0) | |
60 | mask = 1; | |
61 | printf("%#x\n", mask); | |
62 | }' < /dev/null` | |
63 | n=$(($n+1)) | |
64 | if ! taskset -p $cpumask $$ > /dev/null 2>&1 | |
65 | then | |
66 | echo taskset failure: '"taskset -p ' $cpumask $$ '"' | |
67 | exit 1 | |
68 | fi | |
69 | ||
70 | # Sleep a random duration | |
71 | sleeptime=`awk -v me=$me -v n=$n -v sleepmax=$sleepmax 'BEGIN { | |
72 | srand(n + me + systime()); | |
73 | printf("%06d", int(rand() * sleepmax)); | |
74 | }' < /dev/null` | |
75 | n=$(($n+1)) | |
76 | sleep .$sleeptime | |
77 | ||
78 | # Spin a random duration | |
79 | limit=`awk -v me=$me -v n=$n -v spinmax=$spinmax 'BEGIN { | |
80 | srand(n + me + systime()); | |
81 | printf("%06d", int(rand() * spinmax)); | |
82 | }' < /dev/null` | |
83 | n=$(($n+1)) | |
84 | for i in {1..$limit} | |
85 | do | |
86 | echo > /dev/null | |
87 | done | |
88 | done | |
89 | ||
90 | exit 1 |