Cable verdict folded into one console cell (length green, fault name red, xover amber, fail; diag rule lines and counters-reset line gone), reset fires at the press not diag completion, and the measure's blip is suppressed at every counter source instead of counted-hidden-reverted: worker error adds, loss-window write-offs (quiet slides state without charging; leaving the quiet era presumes in-window holes delivered so the gap's tail is never charged late), NIC poller tracks raw without accumulating, socket drops discarded, modules un-primed by the measure itself; display hold deleted so pre-existing errors no longer blink out during a measure
This commit is contained in:
@@ -12,12 +12,13 @@ const (
|
||||
)
|
||||
|
||||
type lossWindow struct {
|
||||
mu sync.Mutex
|
||||
base uint64
|
||||
inited bool
|
||||
bits []uint64
|
||||
lost atomic.Uint64
|
||||
late atomic.Uint64
|
||||
mu sync.Mutex
|
||||
base uint64
|
||||
inited bool
|
||||
quietEra bool
|
||||
bits []uint64
|
||||
lost atomic.Uint64
|
||||
late atomic.Uint64
|
||||
|
||||
// The sending half of this stream. Both halves are in this process and the
|
||||
// receiving socket ignores its own outgoing frames, so this window is fed by
|
||||
@@ -47,11 +48,24 @@ func newLossWindows(tx []*txStats) []lossWindow {
|
||||
// the run. Nothing that arrives later is evidence enough to undo that, which is
|
||||
// why the sender's own frontier is the guard rather than a limit on how far a
|
||||
// single step may move.
|
||||
func (w *lossWindow) observe(seq uint64) bool {
|
||||
// quiet slides the window without charging: gaps written off during a cable
|
||||
// measure are its own link blip, suppressed at the source while the state
|
||||
// machine stays in sync with the wire.
|
||||
func (w *lossWindow) observe(seq uint64, quiet bool) bool {
|
||||
if seq >= w.sent.Load() {
|
||||
return false
|
||||
}
|
||||
w.mu.Lock()
|
||||
if w.quietEra && !quiet {
|
||||
// Leaving a measure: the window was full when it began, so every hole
|
||||
// still inside went missing while failures were suppressed. Marking
|
||||
// them delivered keeps the write-off complete however the eviction
|
||||
// timing falls, instead of charging the gap's in-window tail later.
|
||||
for i := range w.bits {
|
||||
w.bits[i] = ^uint64(0)
|
||||
}
|
||||
}
|
||||
w.quietEra = quiet
|
||||
if !w.inited {
|
||||
// Start half a window below the first sequence seen, so anything the
|
||||
// sender put on the wire before it lands inside the window rather than
|
||||
@@ -63,11 +77,13 @@ func (w *lossWindow) observe(seq uint64) bool {
|
||||
}
|
||||
if seq < w.base {
|
||||
w.mu.Unlock()
|
||||
w.late.Add(1)
|
||||
if !quiet {
|
||||
w.late.Add(1)
|
||||
}
|
||||
return true
|
||||
}
|
||||
if seq >= w.base+lossSlots {
|
||||
w.evict(seq - lossSlots + 1)
|
||||
w.evict(seq-lossSlots+1, quiet)
|
||||
}
|
||||
idx := seq & (lossSlots - 1)
|
||||
w.bits[idx>>6] |= 1 << (idx & 63)
|
||||
@@ -75,7 +91,7 @@ func (w *lossWindow) observe(seq uint64) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *lossWindow) evict(newBase uint64) {
|
||||
func (w *lossWindow) evict(newBase uint64, quiet bool) {
|
||||
span := newBase - w.base
|
||||
if span >= lossSlots {
|
||||
var missing uint64
|
||||
@@ -83,7 +99,9 @@ func (w *lossWindow) evict(newBase uint64) {
|
||||
missing += uint64(64 - bits.OnesCount64(w.bits[i]))
|
||||
w.bits[i] = 0
|
||||
}
|
||||
w.lost.Add(missing + span - lossSlots)
|
||||
if !quiet {
|
||||
w.lost.Add(missing + span - lossSlots)
|
||||
}
|
||||
w.base = newBase
|
||||
return
|
||||
}
|
||||
@@ -97,6 +115,8 @@ func (w *lossWindow) evict(newBase uint64) {
|
||||
}
|
||||
w.bits[word] &^= bit
|
||||
}
|
||||
w.lost.Add(missing)
|
||||
if !quiet {
|
||||
w.lost.Add(missing)
|
||||
}
|
||||
w.base = newBase
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user