fix: a clock glitch is bridged and a channel is known by name, so a capture keeps its t0
Two defects behind one report ("a trigger during a capture overrides the first,
and the hold-off does not apply"); the second is also what made a spike in one
channel look like the acquisition resetting.
The trigger engine keyed its invalidation on the trigger channel's *index*, which
every rebuild of the channel list renumbers -- enabling a signal that sorts before
it is enough. Any rebuild therefore abandoned an open capture and set no hold-off,
so the next edge inside the post window became t0. It keys on the channel's name
now, which changes only when the source genuinely does.
A packet whose stamps jump more than 256 packet spans ahead is now rejected as a
fault and *bridged* at the declared cadence, instead of poisoning the monotonic
mark (which pinned every later packet flat at the glitched value) and condemning
the next good packet. Only four consecutive failures abandon the declared time
signal, and that fallback no longer wipes the rings: the arrival clock is anchored
to continue from the monotonic mark, so the history is still on one timeline --
the wipe is what made one glitching packet look like the stream restarting from 0.
The declared unit is resolved before those checks, since they weigh the stamps
against a cadence in seconds.
Guards: UDPSCOPE_PROBE_TRIGRENUM_MS prints t0_held=1 through the real widgets,
and the mock's --time-glitch-at/--time-glitch-by injects the clock fault.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
4003084648
commit
f179fbbb44
13 files changed
+406
-96
No files matched your search
@@ -94,6 +94,20 @@ Two lines of the self-check output are assertions in disguise:
|
||||
`events` does not move**: no event fired, so the partial publish deliberately leaves
|
||||
`trigger_latches()` alone — which is also what keeps the `trigger events: N total, M at
|
||||
the disarm` line in the dump meaning what it says.
|
||||
- `[trigrenum-probe] window=W event_span=S pre_pct=P post=O holdoff=H level=L edge=E mode=M
|
||||
enabled=1 armed=1 ch=C channels=N`, then `capture open: t0=T ch=C -- enabling signal 1 now`,
|
||||
`after enable: trigger ch=C' channels=N'`, and `latched t0=T' opened on T t0_held=D` (stderr,
|
||||
`UDPSCOPE_PROBE_TRIGRENUM_MS`) — the first line is the geometry the real widgets produced
|
||||
(`window=1.0000 event_span=1.0000 pre_pct=10.0 post=0.9000` for the reported setup); it is
|
||||
context, not the assertion. The third must show the index **actually moving** (`ch=0` →
|
||||
`ch=1`), or the probe tested nothing — the sine has to be a channel that sorts before the
|
||||
square. **`t0_held=1` is the assertion**: the capture that opened on `T` latched on `T`, so the
|
||||
renumber neither abandoned it nor let a later edge inside the post window become t0. With the
|
||||
engine's invalidation keyed on the channel's index instead of its name this read `t0_held=0`,
|
||||
with `pending` back to 0 and `holdoff_until` *behind* `now_t` on the engine line — i.e. no
|
||||
hold-off was set at all, which is the whole defect. The `[udpscope] trigger: edge at ... got
|
||||
[--0.0199..0.9000]` beside it is expected: the rebuild replaces the `BufferStore`, so the
|
||||
surviving capture has no pre side left and reports a negative `pre_s`.
|
||||
- `[export-probe] mode=.. axis=[a..b] rows=N cols=M time=[c..d] abs=[..]` (stderr,
|
||||
`UDPSCOPE_EXPORT_MS`) — **`time=` must equal `axis=`** and **`rows=` must be the
|
||||
span times the stream's real rate, plus one** (2 s at 10 kS/s is 20001). The export
|
||||
|
||||
Reference in new issue
Block a user