← board

est_mem is a guess, and the one number we checked was 8x wrong

The measurement

testmgr.py schedules against a per-class table:

"unit":        {"est_mem": 700 << 20,  "timeout": 90},
"qemu":        {"est_mem": 800 << 20,  "timeout": 240},
"selfhost":    {"est_mem": 1200 << 20, "timeout": 600},
"corpus":      {"est_mem": 1400 << 20, "timeout": 1200},
"conformance": {"est_mem": 1000 << 20, "timeout": 1200},
"opt":         {"est_mem": 700 << 20,  "timeout": 900},

Measured peak RSS on x86_64, self-hosted binary at 19ee697d3:

workload est_mem says actually
self-compile (compiler.pas + all .inc, 5.6 MB of source) 1200 MB 156 MB
test/hello.pas (unit) 700 MB 24 MB

The fixedpoint compiles twice but sequentially, so peak stays ~156 MB rather than doubling.

The bss=151388300B in every build line is a ~151 MB reservation of static arrays, not resident cost — only touched pages land in RSS. That is almost certainly where the 1200 MB guess came from, and it is why reading the ELF header instead of measuring gets this wrong in the same direction every time.

Why it costs something in both directions

Asked for

  1. Measure peak RSS per job class rather than estimating — the runner already supervises each job, so wait4()'s ru_maxrss for the child is free and exact, no sampling loop needed.
  2. Feed the measurements back: either a checked-in table regenerated from a measuring run, or a small per-host learned file. Prefer the checked-in table — a learned file is per-box state the fleet cannot review, and this is exactly the kind of number that should be visible in a diff.
  3. Whatever lands must keep a conservative floor: an estimate that is too low invites the OOM killer, which is far worse than under-packing. Bias the derived numbers upward (say max observed × 1.5) rather than using the mean.
  4. Confirm the arm32 figure on real hardware before relying on it — the 156 MB is x86_64, and the ILP32 argument is a prediction, not a measurement.

Gate

Report the per-class measured peak in a run's own header alongside jobs=N cap=N scale=N, then show that a full run on this box schedules more jobs concurrently at the same or lower peak machine memory pressure. No OOM, no swap-gate trips.