Skip to content

Commit 8e596ce

Browse files
committed
bench: make every timeout a hard deadline
Plain `timeout` only sends SIGTERM, which the JVM behind the `bal` shell wrapper is free to ignore, so none of the limits actually bounded the run. Wrap every invocation in `timeout -k`, which follows up with SIGKILL after a grace period (KILL_GRACE, default 10s). A SIGKILLed child exits 137 rather than 124, so both the correctness-gate and timing-run classifiers now share a `timed_out` helper that accepts either; without it a hard timeout would be misreported as a generic failure. Output and exit behaviour are otherwise unchanged.
1 parent 5584115 commit 8e596ce

1 file changed

Lines changed: 13 additions & 6 deletions

File tree

scripts/benchmark_vs_scan.sh

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,18 @@ echo
103103
# A timing comparison is only meaningful if both tools actually did the work and
104104
# found the same things. Run each once, unsuppressed, and diff the findings
105105
# before any number is reported.
106+
# `bal` is a shell wrapper around a JVM, which need not die on the SIGTERM that
107+
# plain `timeout` sends. `-k` follows up with SIGKILL so every limit below is a
108+
# hard deadline and the benchmark cannot hang. A SIGKILLed child reports 137.
109+
KILL_GRACE="${KILL_GRACE:-10}"
110+
hard_timeout() { timeout -k "$KILL_GRACE" "$@"; }
111+
timed_out() { [ "$1" -eq 124 ] || [ "$1" -eq 137 ]; }
112+
106113
run_or_die() { # label timeout cmd...
107114
local label="$1" limit="$2"; shift 2
108115
local out status
109-
out=$(timeout "$limit" "$@" 2>&1); status=$?
110-
if [ "$status" -eq 124 ]; then
116+
out=$(hard_timeout "$limit" "$@" 2>&1); status=$?
117+
if timed_out "$status"; then
111118
echo "$label timed out after ${limit}s" >&2; exit 1
112119
elif [ "$status" -ne 0 ]; then
113120
echo "$label failed (exit $status):" >&2; echo "$out" >&2; exit 1
@@ -149,22 +156,22 @@ median() { sort -n | awk '{a[NR]=$1} END {print (NR%2) ? a[(NR+1)/2] : (a[NR/2]+
149156
# Timed runs stay quiet for clean measurement, but a nonzero exit or a timeout
150157
# invalidates the sample rather than being recorded as a fast run.
151158
check_timed() { # label status
152-
if [ "$2" -eq 124 ]; then echo "$1 timed out during timing run" >&2; exit 1
159+
if timed_out "$2"; then echo "$1 timed out during timing run" >&2; exit 1
153160
elif [ "$2" -ne 0 ]; then echo "$1 failed during timing run (exit $2)" >&2; exit 1; fi
154161
}
155162

156163
# JVM floor: what `bal` costs before doing any analysis at all.
157164
jvm_times=()
158165
for _ in $(seq 1 "$RUNS"); do
159-
s=$(date +%s%N); (cd "$PKG" && timeout 300 "$BAL" version >/dev/null 2>&1); status=$?; e=$(date +%s%N)
166+
s=$(date +%s%N); (cd "$PKG" && hard_timeout 300 "$BAL" version >/dev/null 2>&1); status=$?; e=$(date +%s%N)
160167
check_timed "bal version" "$status"
161168
jvm_times+=( $(( (e - s) / 1000000 )) )
162169
done
163170
JVM=$(printf '%s\n' "${jvm_times[@]}" | median)
164171

165172
scan_times=()
166173
for _ in $(seq 1 "$RUNS"); do
167-
s=$(date +%s%N); (cd "$PKG" && timeout 900 "$BAL" scan >/dev/null 2>&1); status=$?; e=$(date +%s%N)
174+
s=$(date +%s%N); (cd "$PKG" && hard_timeout 900 "$BAL" scan >/dev/null 2>&1); status=$?; e=$(date +%s%N)
168175
check_timed "bal scan" "$status"
169176
scan_times+=( $(( (e - s) / 1000000 )) )
170177
done
@@ -173,7 +180,7 @@ SCAN=$(printf '%s\n' "${scan_times[@]}" | median)
173180
blz_times=()
174181
for _ in $(seq 1 "$RUNS"); do
175182
s=$(date +%s%N)
176-
(cd "$PKG" && for f in *.bal; do timeout 300 "$BLZ" "$f" >/dev/null 2>&1 || exit $?; done)
183+
(cd "$PKG" && for f in *.bal; do hard_timeout 300 "$BLZ" "$f" >/dev/null 2>&1 || exit $?; done)
177184
status=$?
178185
e=$(date +%s%N)
179186
check_timed "blazelint" "$status"

0 commit comments

Comments
 (0)