jitter.sh 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0+
  3. #
  4. # Alternate sleeping and spinning on randomly selected CPUs. The purpose
  5. # of this script is to inflict random OS jitter on a concurrently running
  6. # test.
  7. #
  8. # Usage: jitter.sh me jittering-path duration [ sleepmax [ spinmax ] ]
  9. #
  10. # me: Random-number-generator seed salt.
  11. # duration: Time to run in seconds.
  12. # jittering-path: Path to file whose removal will stop this script.
  13. # sleepmax: Maximum microseconds to sleep, defaults to one second.
  14. # spinmax: Maximum microseconds to spin, defaults to one millisecond.
  15. #
  16. # Copyright (C) IBM Corporation, 2016
  17. #
  18. # Authors: Paul E. McKenney <paulmck@linux.ibm.com>
  19. me=$(($1 * 1000))
  20. jittering=$2
  21. duration=$3
  22. sleepmax=${4-1000000}
  23. spinmax=${5-1000}
  24. n=1
  25. starttime=`gawk 'BEGIN { print systime(); }' < /dev/null`
  26. nohotplugcpus=
  27. for i in /sys/devices/system/cpu/cpu[0-9]*
  28. do
  29. if test -f $i/online
  30. then
  31. :
  32. else
  33. curcpu=`echo $i | sed -e 's/^[^0-9]*//'`
  34. nohotplugcpus="$nohotplugcpus $curcpu"
  35. fi
  36. done
  37. while :
  38. do
  39. # Check for done.
  40. t=`gawk -v s=$starttime 'BEGIN { print systime() - s; }' < /dev/null`
  41. if test "$t" -gt "$duration"
  42. then
  43. exit 0;
  44. fi
  45. # Check for stop request.
  46. if ! test -f "$jittering"
  47. then
  48. exit 1;
  49. fi
  50. # Set affinity to randomly selected online CPU
  51. if cpus=`grep 1 /sys/devices/system/cpu/*/online 2>&1 |
  52. sed -e 's,/[^/]*$,,' -e 's/^[^0-9]*//'`
  53. then
  54. :
  55. else
  56. cpus=
  57. fi
  58. # Do not leave out non-hot-pluggable CPUs
  59. cpus="$cpus $nohotplugcpus"
  60. cpumask=`awk -v cpus="$cpus" -v me=$me -v n=$n 'BEGIN {
  61. srand(n + me + systime());
  62. ncpus = split(cpus, ca);
  63. print ca[int(rand() * ncpus + 1)];
  64. }' < /dev/null`
  65. n=$(($n+1))
  66. if ! taskset -c -p $cpumask $$ > /dev/null 2>&1
  67. then
  68. echo taskset failure: '"taskset -c -p ' $cpumask $$ '"'
  69. exit 1
  70. fi
  71. # Sleep a random duration
  72. sleeptime=`awk -v me=$me -v n=$n -v sleepmax=$sleepmax 'BEGIN {
  73. srand(n + me + systime());
  74. printf("%06d", int(rand() * sleepmax));
  75. }' < /dev/null`
  76. n=$(($n+1))
  77. sleep .$sleeptime
  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. exit 1