From d3328ebe3bb7133ad615f78d9800fe7e0d830bf2 Mon Sep 17 00:00:00 2001 From: eunhhu Date: Tue, 29 Sep 2026 07:47:00 +0100 Subject: Apply a link's records in transport.c as a host does From the one after the last heard, letting be the ones heard before and stopping at a gap: the listener's first delivery may begin past it when packets reorder, which the harness counted as wrong. --- research/experiments/019-idle-links/transport.c | 31 ++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/research/experiments/019-idle-links/transport.c b/research/experiments/019-idle-links/transport.c index 8ff34a4..0ce693a 100644 --- a/research/experiments/019-idle-links/transport.c +++ b/research/experiments/019-idle-links/transport.c @@ -41,24 +41,33 @@ static uint32_t timeline[BUCKETS]; static uint64_t now_ns(void); -/* Records as sent, each once, in order: the one after the last taken on - * (one taken before would be a delivery again), of the payload's bytes. */ +/* Records applied as a host does: from the one after the last taken on, + * each as sent (else wrong); ones taken before are let be (the listener + * does not know yet how far this side heard: its first delivery after the + * link starts may begin anywhere); a gap stops it, and says so. */ static bool deliver(void *context, const PureLinkDelivery *d) { (void)context; const unsigned char *at = d->records; + uint64_t now = now_ns(), took = 0; + bool gap = false; for (unsigned k = 0; k < d->count; ++k) { uint32_t size = (uint32_t)at[0] | (uint32_t)at[1] << 8 | (uint32_t)at[2] << 16 | (uint32_t)at[3] << 24; - if (d->first + k != heard + 1 + k || size != payload_size || memcmp(at + 4, payload, size)) ++wrong; + uint64_t seq = d->first + k; + if (seq > heard + 1) { + gap = true; + break; + } + if (seq == heard + 1) { + if (size != payload_size || memcmp(at + 4, payload, size)) ++wrong; + if (queued_at) waited[seq] = now - queued_at[seq]; + heard = seq; + ++took; + } at += 4 + size; } - uint64_t now = now_ns(); - if (queued_at) - for (unsigned k = 0; k < d->count; ++k) waited[d->first + k] = now - queued_at[d->first + k]; - if ((now - began) / 100000000u < BUCKETS) timeline[(now - began) / 100000000u] += d->count; - if ((size_t)(at - d->records) != d->size || d->first > heard + 1) ++wrong; - if (d->first + d->count - 1 > heard) heard = d->first + d->count - 1; - atomic_fetch_add(&delivered, d->count); - pure_link_done(listener, d->token, heard, true, false); + if ((now - began) / 100000000u < BUCKETS) timeline[(now - began) / 100000000u] += (uint32_t)took; + atomic_fetch_add(&delivered, took); + pure_link_done(listener, d->token, heard, true, gap); return true; } -- cgit v1.2.3