Judge loss by arrival order and a deadline, one tx ring per stream

This commit is contained in:
flamingcow
2026-08-31 14:33:09 -07:00
parent 06fa759b1a
commit 7fa48da73c
12 changed files with 220 additions and 254 deletions
+12 -3
View File
@@ -28,6 +28,8 @@ type direction struct {
// Guards everything the sampler touches. Collection consumes self-clearing
// sources, so a second concurrent reader would see a gap.
iface int
mu sync.Mutex
prev sample
nic *nicCounters
@@ -214,8 +216,14 @@ type view struct {
// One tick of every counter this direction owns, flattened to deltas: the
// worker counters grow forever, the socket drop statistic clears itself on
// read, and the nic counters re-base, none of which survives past here.
// read, and the nic counters re-base, none of which survives past here. The
// loss judge runs first, so a silent wire's charges are on the books before
// the read.
func (d *direction) collect() (frames, bytes uint64, e errs) {
now := time.Now()
for i := range d.streams {
d.streams[i].judge(now)
}
cur := d.snapshot()
prev := d.prev
d.prev = cur
@@ -308,7 +316,7 @@ func (d *direction) primeCounters() {
d.mu.Unlock()
}
func buildDirection(label string, tx, rx endpoint, masked *atomic.Bool) (*direction, error) {
func buildDirection(label string, iface int, tx, rx endpoint, masked *atomic.Bool) (*direction, error) {
// Built before the windows, since each window judges sequence numbers against
// the frontier its own sender publishes.
txs := make([]*txStats, numStreams)
@@ -316,6 +324,7 @@ func buildDirection(label string, tx, rx endpoint, masked *atomic.Bool) (*direct
txs[i] = &txStats{}
}
d := &direction{
iface: iface,
txStats: txs,
streams: newLossWindows(txs),
masked: masked,
@@ -360,6 +369,7 @@ func (d *direction) start(wg *sync.WaitGroup, done *atomic.Bool, rxReady *sync.W
w := &txWorker{
fd: fd,
stream: uint16(i),
cpu: txCPU(d.iface, i),
spec: d.specs[i],
batch: batchSize,
stats: d.txStats[i],
@@ -380,7 +390,6 @@ func (d *direction) start(wg *sync.WaitGroup, done *atomic.Bool, rxReady *sync.W
spec: d.specs[i],
stats: d.rxStats[i],
loss: &d.streams[i],
masked: d.masked,
ready: rxReady,
}
wg.Add(1)