Skip to content

[M1-SYS-03] Per-system timing + budget enforcement (G-R5) - #27

Merged
offdev merged 2 commits into
masterfrom
m1-sys-03-system-timing
Sep 14, 2026
Merged

offdev merged 2 commits into
masterfrom
m1-sys-03-system-timing

Conversation

@offdev

@offdev offdev commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Scope

M1-SYS-03 exactly, nothing else (roadmap/M1-heartbeat.md): per-system timing + budget enforcement (G-R5).

  • World::runSystems times each system's own run (TimeIt around the run function) and hands the sample to a new World::checkSystemBudget (src/laige-sim/system_timing.cpp).
  • Rolling window per system: M0-CORE-08 Histogram, fixed capacity kSystemTimingWindowSamples (64 ≈ 1.1 s @ 60 Hz), O(1) no-alloc record, drop-oldest, rolls across ticks (not per-frame).
  • G-R5 enforcement: measured > 1× budget → system/budget_overrun (Warn); measured >= 3× budget (kBudgetCriticalMultiplier) → system/budget_critical (Error); a 3× run fires both. NFR-13.3 5-field grammar (build-stable text, dynamic values as fields system/id/measured_ms/budget_ms/p99_ms/window_samples), rate-limited per (subsystem, event, severity). Over-budget systems are still run — observation, never a gate.
  • Profiler feed (M1-PROF-02): World::systemTimingStats(SystemId) (O(1) pure query) + World::systemTimingWindow(SystemId) (const Histogram* for the frame graph's budgetCheck).
  • Measured times are diagnostics only (ARCH-009) — never enter authoritative state/hashes/replays.

New public API (additive, laige-api.json 496 → 505 symbols)

SystemTimingStats (+4 members), kSystemTimingWindowSamples, kBudgetCriticalMultiplier, World::systemTimingStats, World::systemTimingWindow.

Tests

New SystemTiming suite (8 tests), CTest entry system_timing (the step's Verify command; in the TSan property list): healthy ticks log nothing; over-budget warns at the documented multiplier (second tick rate-limited, rate_limited summary on shutdown); critical system warns then errors in one tick; rolling window drops oldest; NFR-13.3 grammar check; query validation; state travels with move; zero-allocation window (non-sanitizer trees: 100 ticks × 2 systems → allocs=0).

Verification (all local trees)

  • ctest -R system_timing green; full suite 43/43 on build (Debug GCC 16.2.1), build-asan (leak-free), build-tsan, build-clang, build-release, build-shared.
  • Zero new warnings (-Wall -Werror); tools/laige-include-lint OK (28 files).
  • laige-api.json regenerated; api-real-tree green.

Docs (same change, DOC-007)

New docs/api/system_timing.md; cross-refs in docs/api/scheduler.md, docs/api/system_registry.md, docs/README.md, src/laige-sim/README.md.

Compatibility

Additive only — no existing symbol or behavior changed. No ENGINE-RULE-EXCEPTION added.

Unverified paths

  • Windows CI (MSVC) runs on the PR — not tested locally.
  • Wall-clock burn tests are machine-independent by design (steady_clock-driven; asserted bounds leave preemption margin).

@offdev
offdev merged commit 0eeec56 into master Sep 14, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant