#!/usr/bin/env bash # Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License. # See LICENSE.md for license information. # SPDX-License-Identifier: MIT # # Headless UBER perf capture for the Amiga (FS-UAE). # # Stages the built Amiga binaries + DATA into a scratch directory-HD # with an s/startup-sequence that auto-runs Uber, boots A500/OCS from # the real Kickstart on a private Xvfb display, polls the staged # joeylog.txt until UBER prints its "press any key to exit" completion # marker (or a wall-clock timeout), then kills the emulator and copies # the log to build/amiga/bin/joeylog.txt for build/tools/uberPerfTable. # # scripts/bench-amiga.sh # default 150s timeout # TIMEOUT=240 scripts/bench-amiga.sh # override # BENCH_PROG=Uberprob BENCH_BIN_DIR=build/amiga/probe scripts/bench-amiga.sh # # another build of UBER (the probe: # # scripts/verify-amiga-display.sh) # # Real Kickstart (installer component `kickstart`) is # required -- the HAL drives OCS directly and AROS is unreliable for it. set -euo pipefail repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) source "$repo/scripts/lib/joeyEnv.sh" joeyNeed FSUAE fsuae source "$repo/scripts/lib/amigaGate.sh" amigaMachine bin_dir=${BENCH_BIN_DIR:-$repo/build/amiga/bin} prog=${BENCH_PROG:-Uber} timeout_s=${TIMEOUT:-150} if [[ ! -f $bin_dir/$prog ]]; then echo "$prog not built in $bin_dir. Run 'make amiga' first." >&2 exit 1 fi work=$(mktemp -d -t joeylib-amiga-bench.XXXXXX) mkdir -p "$work/s" find "$bin_dir" -maxdepth 1 -type f -executable -exec cp -t "$work/" {} + # A probe build's folder has no DATA of its own: UBER's is the main build's. if [[ -d "$bin_dir/DATA" ]]; then cp -r "$bin_dir/DATA" "$work/" elif [[ -d "$repo/build/amiga/bin/DATA" ]]; then cp -r "$repo/build/amiga/bin/DATA" "$work/" fi # ':' anchors to the boot volume root. 32 KB task stack: the shell # default (~4 KB) left UBER one deep call chain from overflow -- the # Phase-1 sprite-compile path found it (emitter accumulator frame + # vsnprintf underneath = nondeterministic wandering crashes). printf 'stack 32768\n:%s\n' "$prog" > "$work/s/startup-sequence" log=$work/joeylog.txt display=:$((90 + RANDOM % 9)) Xvfb "$display" -screen 0 800x600x24 -nolisten tcp >/dev/null 2>&1 & xvfb_pid=$! sleep 0.4 cleanup() { joeyStop "$fs_pid" kill "$xvfb_pid" 2>/dev/null || true wait 2>/dev/null || true rm -rf "$work" } trap cleanup EXIT echo "bench-amiga: running UBER headless (timeout ${timeout_s}s)..." >&2 DISPLAY=$display "$FSUAE" \ "${AMIGA_MACHINE_ARGS[@]}" \ --fast_memory=2048 \ --hard_drive_0="$work" \ --hard_drive_0_label=JOEYLIB \ --automatic_input_grab=0 \ --fullscreen=0 \ --fade_out_duration=0 \ >/tmp/bench-amiga-fsuae.log 2>&1 & fs_pid=$! waited=0 while (( waited < timeout_s )); do if [[ -f $log ]] && grep -q "press any key to exit" "$log" 2>/dev/null; then break fi sleep 2 (( waited += 2 )) || true done if [[ ! -f $log ]]; then echo "bench-amiga: FAIL -- no joeylog.txt produced" >&2 exit 1 fi cp "$log" "$bin_dir/joeylog.txt" ops=$(grep -c "ops/sec" "$log" || true) done_marker=$(grep -c "press any key to exit" "$log" || true) if (( done_marker == 0 )); then echo "bench-amiga: WARNING -- timed out before completion marker (partial capture)" >&2 fi echo "bench-amiga: captured $ops op lines (complete=$done_marker) in ${waited}s" >&2 echo " -> $bin_dir/joeylog.txt" >&2 grep "UBER:" "$log" | sed 's/ | hash=.*//' || true