#!/usr/bin/env bash # A fake /sys for the CPU guard, so heat can be simulated without heat. Point the # program at it with [Thermal] sysfs_root = (config.ini or hardware.ini) # and change the temperature while it runs. # # tools/thermal-sim/fake-temp.sh init # build the tree (4 cores, 3.6 GHz, 70 C) # tools/thermal-sim/fake-temp.sh # set the CPU temperature # tools/thermal-sim/fake-temp.sh throttle # ...and count one throttle event # tools/thermal-sim/fake-temp.sh clock # set every core's clock # tools/thermal-sim/fake-temp.sh ramp # # walk the temperature, throttling # # at 90 C and above # # The tree has no proc/stat, so the program reads the real /proc/stat: how busy # the CPU is stays real (raise it with heat-load.sh). set -euo pipefail usage() { sed -n '2,15p' "$0" >&2; exit 2; } [[ $# -ge 2 ]] || usage root=$1; shift cpu=$root/sys/devices/system/cpu zone=$root/sys/class/thermal/thermal_zone0 init() { rm -f "$root/proc/stat" # an older tree's frozen copy would hide the real one mkdir -p "$zone" echo x86_pkg_temp > "$zone/type" echo 70000 > "$zone/temp" for c in 0 1 2 3; do mkdir -p "$cpu/cpu$c/cpufreq" "$cpu/cpu$c/thermal_throttle" echo 2800000 > "$cpu/cpu$c/cpufreq/scaling_cur_freq" echo 3600000 > "$cpu/cpu$c/cpufreq/cpuinfo_max_freq" echo 3600000 > "$cpu/cpu$c/cpufreq/scaling_max_freq" echo 0 > "$cpu/cpu$c/thermal_throttle/package_throttle_count" echo 0 > "$cpu/cpu$c/thermal_throttle/core_throttle_count" done echo "fake tree ready at $root: 70 C, 2.8 of 3.6 GHz" } set_temp() { # [throttle] echo $(( $1 * 1000 )) > "$zone/temp" if [[ ${2:-} == throttle ]]; then f=$cpu/cpu0/thermal_throttle/package_throttle_count echo $(( $(cat "$f") + 1 )) > "$f" fi } [[ $1 == init ]] && { init; exit 0; } [[ -d $zone ]] || { echo "$0: no tree at $root - run '$0 $root init' first" >&2; exit 1; } case $1 in clock) [[ $# -eq 2 ]] || usage for c in "$cpu"/cpu[0-9]*; do echo $(( $2 * 1000 )) > "$c/cpufreq/scaling_cur_freq"; done echo "clock $2 MHz" ;; ramp) [[ $# -eq 5 ]] || usage from=$2 to=$3 step=$4 secs=$5 (( from > to )) && step=$(( -step )) t=$from while :; do echo "$(date +%T) $t C" # Hold the step; at 90 C and up the CPU throttles, one counted # event every 2 s. for (( i = 0; i < secs; i += 2 )); do if (( t >= 90 )); then set_temp "$t" throttle; else set_temp "$t"; fi sleep 2 done (( t == to )) && break t=$(( t + step )) (( (step > 0 && t > to) || (step < 0 && t < to) )) && t=$to done ;; *) [[ $1 =~ ^[0-9]+$ ]] || usage set_temp "$1" "${2:-}" echo "CPU $1 C${2:+, one throttle event}" ;; esac