ReviewOS

zig-utils/zig-js

Runtime: size runnable slots from host capacity

#983
Closed chris opened this 9 days ago ·
9 days ago

Parent: #502 Depends on: #982

Goal

Size the process-wide runtime runnable-slot budget from host capacity by default, while preserving one explicit, inspectable embedder override.

Current behavior

The schema-v4 coordinator from #982 defaults to maxInt(u64), so typed engine threads remain unbounded unless an embedder sets a fixed limit. This completes enforcement but not #502's automatic-bounding requirement.

Scope

  • Replace the temporary unlimited default with one automatic policy: max(1, detected logical CPUs - 1) typed runnable slots. The reserved lane is for the embedder/foreground host mutator, which executes outside the typed engine-thread boundary.
  • Query host capacity through std.Thread.getCpuCount; use a fail-safe single slot when detection fails.
  • Make the public scheduler override nullable: null selects automatic sizing, a number selects an exact fixed limit, zero pauses entry/resume, and maxInt(u64) is an intentional explicit unlimited policy.
  • Expose detected logical CPUs, the automatic host reservation, configured override, effective limit, and policy mode in the coherent machine-readable scheduler snapshot.
  • Reapplying automatic policy refreshes host detection and wakes waiters when effective capacity grows. Lowering capacity continues to grandfather currently runnable threads.
  • Add deterministic policy-function tests for 1, 2, and large logical-CPU counts plus real coordinator tests for automatic/fixed transitions and snapshot invariants.
  • Update the runtime resource documentation and generated docs manifest.

Non-goals

Priority classes, dynamic load sensing, OS affinity/priority, compilation queues, cancellation, and memory-pressure feedback remain separate #502 work.

Acceptance

  • The default effective limit is finite and derived from the detected host count.
  • One-core hosts retain forward progress with one typed slot.
  • Explicit zero/fixed/unlimited policies remain exact and observable.
  • Automatic/fixed transitions preserve active_slots = sum(resource.runnable) and wake blocked entrants only when capacity permits.
  • Focused normal/TSan scheduler tests, full units, runtime-thread audit, and deterministic threadfuzz pass.
  • A local single-thread lifecycle diagnostic shows no material regression from the #982 parent.
9 days ago

Implemented in 7bfffb8 and pushed to main.

The process-wide runnable-slot coordinator now defaults to max(1, detected logical CPUs - 1), reserving one lane for the embedder or foreground host mutator outside the typed engine-thread boundary. Detection uses Zig's cross-platform host query and fails safe to one slot. The public override is nullable: null reapplies and refreshes automatic sizing, numeric values are exact, zero pauses entry/resume, and maxInt(u64) is intentional unlimited capacity.

Schema-v5 telemetry exposes automatic/fixed policy, detected logical CPUs, the automatic host reservation, configured override, effective limit, occupancy, and pressure. Steady-state snapshots retain a lock-free initialized fast path. On this host, 11 logical CPUs resolve to 10 typed slots plus one reserved host lane.

Validation:

  • full units: 2,503 passed, 1 skipped, 0 failed, 0 leaked (2,504 total)
  • focused normal scheduler integration: 4/4 passed, zero leaks
  • focused TSan scheduler integration: 4/4 passed, zero leaks
  • standalone normal and TSan coordinator suites: 6/6 each
  • deterministic threadfuzz: 40/40 programs, 0 failures
  • runtime-thread audit: 6 production call sites across 6 resource classes
  • C API audit: 117/117 declarations, 460 private profile exports
  • docs: 51 pages, manifest stable
  • exact-parent ReleaseFast diagnostic: 0.985 median paired lifecycle ratio over 11 interleaved samples; diagnostic only, not publication evidence

Test262 flips were not measured because the corpus is absent in this checkout.

Sign in to comment on this issue.