fix: NodeSnapshot fields must line up with what nodes supply
a8cfe73appended queued/wake_pending/total_exec_ms to the NodeSnapshot aggregate in an order no call site used. Every node type fills the aggregate positionally and all of them supply total_exec_ms as the element straight after queue_wait_ms — but the struct declared the two bools there. So the exec total landed in `queued`, `queued` landed in `wake_pending`, and `wake_pending` landed in total_exec_ms. GCC reported it as -Wnarrowing (bool to double), 88 times, once per node instantiation across the test build. The build carried on. This is worse than a cosmetic mix-up, because all three fields were added specifically to diagnose a wedge. A wedged pipeline reported total_exec_ms as 0.0 or 1.0, and `queued` as "has this node ever run" — true for every node that had, including ones asleep with nothing to do. The web debug JSON served the same values. Anyone reading them to find the stalled node would have been pointed at the wrong one. Moves total_exec_ms above the two bools to match every call site, and notes in the struct why the order is load-bearing. Verified in both directions: ona8cfe73the new case reports frames=8 total=0 queued=true; here total >= ema and both flags are false.
This commit is contained in:
@@ -157,6 +157,16 @@ struct NodeSnapshot {
|
||||
double cpu_util_pct; // exec_ms / (exec_ms + blocked_ms) * 100
|
||||
double queue_wait_ms{0}; // PoolNode: cumulative time spent in pool queue
|
||||
|
||||
// Cumulative wall time inside fire_once. Unlike ema_exec_ms this is a true
|
||||
// sum, so it is the field to use for "share of the run spent in this node".
|
||||
// Note it still includes time parked pushing into a full output channel;
|
||||
// total_cpu_ms is the part that backpressure cannot inflate.
|
||||
//
|
||||
// Declared before the two bools below because every node type initialises
|
||||
// this aggregate positionally, and all of them supply total_exec_ms as the
|
||||
// element after queue_wait_ms.
|
||||
double total_exec_ms{0};
|
||||
|
||||
// Live scheduling state, for observing the AR-004 invariant "a node never
|
||||
// sleeps with a wake outstanding". The invariant was previously asserted in
|
||||
// comments but invisible at runtime, so a lost wake could only be found in a
|
||||
@@ -169,11 +179,6 @@ struct NodeSnapshot {
|
||||
// queued=1 while nothing running -> submitted but never scheduled
|
||||
bool queued{false};
|
||||
bool wake_pending{false};
|
||||
// Cumulative wall time inside fire_once. Unlike ema_exec_ms this is a true
|
||||
// sum, so it is the field to use for "share of the run spent in this node".
|
||||
// Note it still includes time parked pushing into a full output channel;
|
||||
// total_cpu_ms is the part that backpressure cannot inflate.
|
||||
double total_exec_ms{0};
|
||||
};
|
||||
|
||||
// ── Pool statistics + snapshot ────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user