test: the per-second engine line shows the store's retained span, which pins a stalled clock
Diagnosing "going live from an event view does nothing for ~5 s, with the status bar green" needed a
distinction the engine's own fields cannot make. `n` counts every stored sample, so it climbs whenever data
arrives at all; what says *why* nothing moves is the store's stamp pair beside it. So the line gains
`ring=[oldest..newest] n=`:
trig engine: … history=0.0000/0.4000 s … now_t=2.520 holdoff_until=2.520 ring=[2.5200..2.5200] n=567000
trig engine: … ring=[2.5200..2.5200] n=1131000
trig engine: … ring=[2.5200..2.5200] n=1689000
Three seconds apart, after `<live>`: the sample count climbs at the stream's rate (the data *is* arriving and
being stored) while the retained span is a single value — the file view's last stamp. So the producer's clock
is **frozen** after the restart, not lagging, which is why `history` never fills, why an armed trigger never
latches, and why a live view with the trigger off does not advance either: one cause, two faces, and it is
not the trigger.
The reading is what tells that apart from a stalled *feed* (ring moving, `now_t` still), which is a different
bug with a different fix — and neither is visible from `now_t` alone. `n` climbing beside a still `ring` is
the clock; a moving `ring` beside a still `now_t` is the feed.
The fix itself is the next piece of work: the producer's clock has to advance across a client restart (or the
file view's retained history has to go when going live), and this pair is the assertion it must satisfy —
after `<live>`, `ring` must move within a stream round-trip. Verified: `make test-ui` 14 files; the fields
observed in the transition run above; no `Gtk-CRITICAL`.
This commit is contained in:
1 parent
4e29b958a2
commit
62b5f14504
2 files changed
+35
-2
No files matched your search
@@ -1484,6 +1484,31 @@ which must be untouched:
|
||||
[enable-all-probe] switched 'sine' off: traces_left=0 (want 0) math_off=[math x2,math3] math_on=[math lp] notice=''sine' is off: 1 trace left the plots; math off: math x2 and 1 more'
|
||||
```
|
||||
|
||||
## `trig engine:` — the producer's per-second engine line
|
||||
|
||||
```
|
||||
[udpscope] trig engine: ch=1 armed=1 pending=0 elapsed=0.0000/0.1000 s accum=0 history=0.0000/0.4000 s pre_pct=80 v=1 now_t=2.520 holdoff_until=2.520 ring=[2.5200..2.5200] n=567000
|
||||
```
|
||||
|
||||
Printed by the producer once a second while a trigger is configured, so a run with no trigger at all shows
|
||||
none. `elapsed/post_want` is the capture's progress in stream seconds, `accum` how many samples that window
|
||||
holds, `history/pre` how much pre-trigger history the engine has, and `now_t` the stamp of the last sample
|
||||
the **engine** was fed (`engine.last_t()`), not the stream's time.
|
||||
|
||||
**`ring=[oldest..newest] n=` is the store's own retained span and sample count, and it is the pair that says
|
||||
which of two failures a stalled display is.** `n` counts every stored sample, so it climbs at the stream's
|
||||
rate whenever data arrives at all:
|
||||
|
||||
- **`ring` standing still while `n` climbs** is the *clock*: samples are stored but every one carries the
|
||||
same stamp, so the axis cannot advance and the trigger's `history` never fills. Measured after going live
|
||||
from an event view: `ring=[2.5200..2.5200] n=567000 → n=1131000 → n=1689000`, one second apart, with
|
||||
`now_t` and `holdoff_until` both pinned at `2.520` — the file view's last stamp. The producer's clock was
|
||||
frozen, not lagging, and the display stayed blank until something re-planned the store.
|
||||
- **`ring` advancing while `now_t` does not** is the *feed*: the store is moving and the engine is not being
|
||||
handed the samples, which is a trigger-path question and not a clock one.
|
||||
|
||||
Neither can be read off the engine's own fields, which is why the store's pair is here.
|
||||
|
||||
## `[udpscope] buffer allocated:`
|
||||
|
||||
```
|
||||
|
||||
+10
-2
@@ -917,12 +917,20 @@ void Acquisition::on_data(const udps_frame_t* frame) {
|
||||
std::fprintf(stderr,
|
||||
"[udpscope] trig engine: ch=%d armed=%d pending=%d elapsed=%.4f/%.4f s "
|
||||
"accum=%llu history=%.4f/%.4f s pre_pct=%.0f v=%.4g now_t=%.3f "
|
||||
"holdoff_until=%.3f\n",
|
||||
"holdoff_until=%.3f ring=[%.4f..%.4f] n=%zu\n",
|
||||
trig_channel, int(engine.armed()), int(engine.pending()),
|
||||
engine.post_elapsed(), engine.post_seconds(),
|
||||
static_cast<unsigned long long>(engine.post_accum()), engine.history(),
|
||||
engine.pre_seconds(), tc.pretrigger_pct, engine.last_value(),
|
||||
engine.last_t(), engine.holdoff_until());
|
||||
engine.last_t(), engine.holdoff_until(),
|
||||
// The store's own retained span, beside the engine's view of the clock. Going live
|
||||
// restarts the client, and the question a stalled display raises is whether the *time
|
||||
// ring* is moving at all: `n` climbing while `ring` stands still is a clock problem, and
|
||||
// `ring` moving while `now_t` does not is a feed problem. Neither can be told from the
|
||||
// engine's own fields.
|
||||
store.time().size() > 0 ? double(store.time()[0]) : 0.0,
|
||||
store.time().size() > 0 ? double(store.time()[store.time().size() - 1]) : 0.0,
|
||||
store.time().size());
|
||||
std::fflush(stderr);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user