Bound CI build parallelism so five concurrent jobs stop starving the runner
All checks were successful
akbasic CI Build / cmake_build (push) Successful in 3m33s
akbasic CI Build / sanitizers (push) Successful in 5m1s
akbasic CI Build / coverage (push) Successful in 4m1s
akbasic CI Build / akgl_build (push) Successful in 9m23s
akbasic CI Build / mutation_test (push) Successful in 23m25s

Run #31's sanitizers job failed, and not on anything in src/. The ASan build
reached 100% and the runner's Docker daemon went away before ctest emitted a
single line: "Cannot connect to the Docker daemon at unix:///var/run/docker.sock".

The tree under test is identical to run #30's -- 9e5496f touched only this
file -- and run #30's sanitizers job passed 112/112 in 83 s. What changed is
that #30 was still losing akgl_build and coverage early, so #31 was the first
push on which all five jobs did real work at the same time. All five say
runs-on: ubuntu-latest, so all five share one runner, and every build step
asked for a bare --parallel, i.e. nproc compilers each.

The timestamps are unambiguous. Through 20:36:16 the sanitizers job links an
executable in well under a second. akgl_build starts at 20:36:02 and begins
compiling SDL, SDL_image, SDL_mixer, SDL_ttf, libccd and clay; mutation_test
starts at 20:36:41. From 20:36:16 onward a single `Linking C executable` step
takes one to two minutes -- a sixtyfold regression with no source change --
and at 20:49:55 the daemon is gone. ASan links are memory-hungry and the SDL
tree is large; the runner ran out.

The only lever on that is how many compiler and linker processes exist at
once, so bound each build to 2. Worst case is now 8 rather than 5 x nproc.
mutation_test drives its own builds through the harness and is left alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-03 18:33:01 -04:00
parent 9e5496f6b2
commit 5f1d1cb2e0

View File

@@ -44,10 +44,24 @@ jobs:
run: |
sudo apt-get update -y
sudo apt-get install -y cmake gcc moreutils
# --parallel 2 rather than a bare --parallel, and that bound is measured
# rather than cautious. All five jobs in this file say runs-on:
# ubuntu-latest and land on the same runner, so a bare --parallel asks for
# nproc compilers *per job* and the runner is handed five times that at
# once. Run #30 never showed it because akgl_build and coverage were still
# dying early; run #31 was the first push on which all five did real work
# simultaneously, and the sanitizers job went from a 55-second link phase
# to a 14-minute one -- individual `Linking C executable` steps taking two
# minutes each, starting at the exact second akgl_build began its SDL tree
# -- before the runner's Docker daemon fell over outright and took the job
# with it. That is memory exhaustion, and the only lever on it is the
# number of concurrent compiler and linker processes. Applied at all four
# build sites for the same reason; mutation_test drives its own builds
# through the harness and is not bounded here.
- name: build
run: |
cmake -S . -B build
cmake --build build --parallel
cmake --build build --parallel 2
# The suite is 78 cases: 41 golden files byte-compared against the Go
# reference's own corpus (checked in at tests/reference/, see its README),
# 9 local golden cases for verbs the reference never implemented, 25 unit
@@ -98,7 +112,7 @@ jobs:
cmake -S . -B build-asan \
-DAKBASIC_SANITIZE=ON \
-DCMAKE_BUILD_TYPE=Debug
cmake --build build-asan --parallel
cmake --build build-asan --parallel 2
ctest --test-dir build-asan --output-on-failure
- run: echo "🍏 This job's status is ${{ job.status }}."
@@ -138,7 +152,7 @@ jobs:
cmake -S . -B build-coverage \
-DAKBASIC_COVERAGE=ON \
-DCMAKE_BUILD_TYPE=Debug
cmake --build build-coverage --parallel
cmake --build build-coverage --parallel 2
ctest --test-dir build-coverage --output-on-failure
mkdir -p build-coverage/coverage
gcovr --root . --filter 'src/.*' \
@@ -254,7 +268,7 @@ jobs:
- name: build with libakgl
run: |
cmake -S . -B build-akgl -DAKBASIC_WITH_AKGL=ON
cmake --build build-akgl --parallel
cmake --build build-akgl --parallel 2
# Dummy video and audio drivers, set per test by CMakeLists rather than in
# this job's environment, because an AKGL build of `basic` is now an SDL
# program and the golden cases run *it*: forty-one real windows is not what