oxedyne/fe2o3/fe2o3_austenite/tools/bench/lib/host.sh
3.1 KiB, 1 run
created by r1870400018:60944, which is this file's identity for as long as the history lasts, whatever it is later renamed to
download · who wrote it · its history
| 1 | # Shared bash helpers for the S0 bench harness: host-load reading, the memory |
| 2 | # cap, and one timed run. Sourced, not executed. |
| 3 | |
| 4 | BENCH_LOAD_THRESHOLD="${BENCH_LOAD_THRESHOLD:-2}" # 1-min loadavg above this flags a run (plan §S0) |
| 5 | |
| 6 | # The 1-minute load average, as a bare number. |
| 7 | loadavg1() { |
| 8 | awk '{print $1}' /proc/loadavg |
| 9 | } |
| 10 | |
| 11 | # `some avg10` from /proc/pressure/<resource> (cpu, memory or io), or 0 if PSI |
| 12 | # is not exposed (some kernels/containers disable it) -- absence must not fail |
| 13 | # a run, only leave the PSI field at a documented zero. |
| 14 | psi_avg10() { |
| 15 | local resource="$1" |
| 16 | local f="/proc/pressure/${resource}" |
| 17 | if [[ -r "$f" ]]; then |
| 18 | awk -F'avg10=' '/^some/{split($2,a," "); print a[1]}' "$f" |
| 19 | else |
| 20 | echo "0" |
| 21 | fi |
| 22 | } |
| 23 | |
| 24 | # Is the host loaded right now, by the 1-minute average against the threshold? |
| 25 | host_is_loaded() { |
| 26 | local l1 |
| 27 | l1="$(loadavg1)" |
| 28 | awk -v l="$l1" -v t="$BENCH_LOAD_THRESHOLD" 'BEGIN{exit !(l>t)}' |
| 29 | } |
| 30 | |
| 31 | # Runs one command under the memory cap and /usr/bin/time -v, emitting a single |
| 32 | # JSON line (via jq) to stdout with wall time, peak RSS and before/after host |
| 33 | # load. Args: <doc> <engine> <jobs> <out_jsonl_path> -- <cmd...> |
| 34 | run_timed() { |
| 35 | local doc="$1" engine="$2" jobs="$3" out="$4" |
| 36 | shift 4 |
| 37 | if [[ "$1" != "--" ]]; then |
| 38 | echo "run_timed: expected -- before the command" >&2 |
| 39 | return 2 |
| 40 | fi |
| 41 | shift |
| 42 | |
| 43 | local load_before load_after psi_cpu_before psi_cpu_after psi_mem_before psi_mem_after |
| 44 | load_before="$(loadavg1)" |
| 45 | psi_cpu_before="$(psi_avg10 cpu)" |
| 46 | psi_mem_before="$(psi_avg10 memory)" |
| 47 | |
| 48 | local time_out rss_kb=0 exit_code=0 |
| 49 | time_out="$(mktemp)" |
| 50 | local t0 t1 wall_s |
| 51 | t0=$(date +%s.%N) |
| 52 | systemd-run --user --scope --quiet -p MemoryMax=3G --slice=claude-rc.slice -- \ |
| 53 | /usr/bin/time -v -o "$time_out" -- "$@" \ |
| 54 | > /dev/null 2>&1 |
| 55 | exit_code=$? |
| 56 | t1=$(date +%s.%N) |
| 57 | wall_s=$(awk -v a="$t0" -v b="$t1" 'BEGIN{printf "%.4f", b-a}') |
| 58 | |
| 59 | if [[ -f "$time_out" ]]; then |
| 60 | rss_kb="$(awk -F': ' '/Maximum resident set size/{print $2}' "$time_out")" |
| 61 | [[ -z "$rss_kb" ]] && rss_kb=0 |
| 62 | fi |
| 63 | rm -f "$time_out" |
| 64 | |
| 65 | load_after="$(loadavg1)" |
| 66 | psi_cpu_after="$(psi_avg10 cpu)" |
| 67 | psi_mem_after="$(psi_avg10 memory)" |
| 68 | |
| 69 | local flagged=false |
| 70 | if awk -v a="$load_before" -v b="$load_after" -v t="$BENCH_LOAD_THRESHOLD" \ |
| 71 | 'BEGIN{exit !(a>t || b>t)}'; then |
| 72 | flagged=true |
| 73 | fi |
| 74 | |
| 75 | jq -nc \ |
| 76 | --arg doc "$doc" --arg engine "$engine" --arg jobs "$jobs" \ |
| 77 | --argjson wall_s "$wall_s" --argjson rss_kb "${rss_kb:-0}" \ |
| 78 | --argjson exit_code "$exit_code" \ |
| 79 | --argjson load_before "$load_before" --argjson load_after "$load_after" \ |
| 80 | --argjson psi_cpu_before "$psi_cpu_before" --argjson psi_cpu_after "$psi_cpu_after" \ |
| 81 | --argjson psi_mem_before "$psi_mem_before" --argjson psi_mem_after "$psi_mem_after" \ |
| 82 | --argjson flagged_under_load "$flagged" \ |
| 83 | --arg ts "$(date -u +%FT%TZ)" \ |
| 84 | '{ts:$ts, doc:$doc, engine:$engine, jobs:$jobs, wall_s:$wall_s, rss_kb:$rss_kb, |
| 85 | exit_code:$exit_code, load_before:$load_before, load_after:$load_after, |
| 86 | psi_cpu_before:$psi_cpu_before, psi_cpu_after:$psi_cpu_after, |
| 87 | psi_mem_before:$psi_mem_before, psi_mem_after:$psi_mem_after, |
| 88 | flagged_under_load:$flagged_under_load}' \ |
| 89 | >> "$out" |
| 90 | |
| 91 | return $exit_code |
| 92 | } |