feat: a retained slot can be backfilled without pushing

This commit is contained in:
Martino Ferrari committed 2026-10-08 19:32:47 +02:00
1 parent 2ebf2be571
commit 1ae72d4903
2 files changed
+42

No files matched your search

+18
View File
@@ -64,6 +64,24 @@ class RingBuffer {
for (u64 i = 0; i < n; ++i) push(vs[i]);
}
/// Producer thread only: rewrites the slot at absolute index `absolute`, without pushing.
/// Returns false when that index is not retained -- already overwritten, or not yet
/// produced -- in which case nothing is written.
///
/// This is for *backfill*: a slot pushed as a placeholder and corrected when the data that
/// belongs there arrives late. It is the same race class as `push()` -- one relaxed store
/// into a slot a consumer may be reading, and T is lock-free by the class's static_assert,
/// so a reader sees the old value or the new one and never a torn one. It deliberately does
/// not touch `produced_`: the count fixes which indices a snapshot reads, and an amend
/// changes a value inside that window rather than extending it.
bool amend(u64 absolute, T v) {
const u64 p = produced_.load(std::memory_order_relaxed);
if (absolute >= p) return false;
if (p > cap_ && absolute < p - cap_) return false;
buf_[static_cast<usize>(absolute & mask_)].store(v, std::memory_order_relaxed);
return true;
}
/// Consumer: retained element count, saturating at capacity().
u64 size() const noexcept {
const u64 p = produced_.load(std::memory_order_acquire);