Cycle every payload pattern per packet and always run both directions

This commit is contained in:
flamingcow
2026-07-25 23:03:31 -07:00
parent 0f16edfe61
commit e77574712d
8 changed files with 75 additions and 104 deletions
+16 -23
View File
@@ -10,10 +10,10 @@ import (
)
const (
// A stream number no data stream can take, so a probe is never mistaken for
// payload if one lands on the wrong socket.
probeStream = 0xffff
probeSize = 64
// Above any real stream number, so a probe is never taken for payload.
probeStream = 0xffff
probeSize = 64
probePattern = 0
// The mac has only a handful of transmit stamp slots. Asking faster than it
// can drain them gets slots recycled while a stamp is still outstanding, and
@@ -27,10 +27,9 @@ const (
)
// Both ports hang off one PTP clock, so a transmit stamp from one and a receive
// stamp from the other subtract directly. Both are taken at the mac, so the
// difference is the two phys plus the cable and nothing else: all host time and
// all queueing falls outside the stamped interval, which is why load does not
// move it.
// stamp from the other subtract directly. Both are taken at the mac, so all host
// time and all queueing falls outside the stamped interval, which is why load
// does not move it.
type cableStats struct {
mu sync.Mutex
min int64
@@ -52,10 +51,10 @@ func (v cableView) minText() string {
return commasInt(v.min)
}
// Summing both directions cancels the phy asymmetry between them, which is
// Averaging the two directions cancels the phy asymmetry between them, which is
// about 790ns and swamps any cable, so one direction alone cannot give a length.
func (c config) cableMetres(views []view) (float64, bool) {
if len(views) != 2 {
if len(views) == 0 {
return 0, false
}
var sum float64
@@ -65,7 +64,8 @@ func (c config) cableMetres(views []view) (float64, bool) {
}
sum += float64(v.cable.min)
}
return (sum - c.zeroNS) / c.nsPerM, true
mean := sum / float64(len(views))
return (mean - c.zeroNS) / c.nsPerM, true
}
func (c config) cableText(views []view) string {
@@ -83,8 +83,6 @@ func newCableStats() *cableStats {
}
}
// The two halves are produced by different goroutines in either order, so each
// deposits its stamp and whichever lands second completes the pair.
func (c *cableStats) put(seq uint64, ts int64, tx bool) {
c.mu.Lock()
defer c.mu.Unlock()
@@ -133,8 +131,6 @@ func (c *cableStats) reset() {
c.mu.Unlock()
}
// Sends one small frame at a time and collects its transmit stamp from the
// socket's error queue before sending the next.
type probeSender struct {
fd int
spec *frameSpec
@@ -143,7 +139,7 @@ type probeSender struct {
func (p *probeSender) run(done *atomic.Bool, startTx <-chan struct{}) {
buf := make([]byte, probeSize)
p.spec.prefill(buf)
p.spec.prefill(buf, probePattern)
oob := make([]byte, 512)
scratch := make([]byte, 1)
@@ -156,9 +152,8 @@ func (p *probeSender) run(done *atomic.Bool, startTx <-chan struct{}) {
for !done.Load() {
<-tick.C
// Stamps are matched to sends by position in the queue, so a stamp that
// arrived after its probe gave up would be handed to this one. Discard
// anything left over before sending.
// Stamps are matched to sends by position in the queue, so one that
// arrived after its probe gave up would be handed to this probe.
for {
if _, _, _, _, err := unix.Recvmsg(p.fd, scratch, oob,
unix.MSG_ERRQUEUE|unix.MSG_DONTWAIT); err != nil {
@@ -166,8 +161,8 @@ func (p *probeSender) run(done *atomic.Bool, startTx <-chan struct{}) {
}
}
putHeader(buf, p.spec.patIdx, probeStream, seq, probeSize-minFrame,
p.spec.crcFor[probeSize])
putHeader(buf, probePattern, probeStream, seq, probeSize-minFrame,
p.spec.crcFor[probePattern][probeSize])
err := unix.Send(p.fd, buf, 0)
// The sequence advances even when a probe fails, so a stale receive half
// can never be paired with a later probe that reused its number.
@@ -211,8 +206,6 @@ func (p *probeSender) awaitTx(scratch, oob []byte) (int64, bool) {
}
}
// Reads probes on the far interface, where every frame carries a receive stamp
// from the MAC.
type probeReceiver struct {
fd int
stats *cableStats