fix graph and white background added

This commit is contained in:
Ayzen
2026-10-15 14:46:06 +03:00
parent 5102ed751c
commit 9a9b8ce5c7
35 changed files with 730 additions and 463 deletions
@@ -29,7 +29,7 @@ class ShmRing {
// Pushes payload with overwrite-oldest policy on overflow.
[[nodiscard]] auto push(std::span<const std::uint8_t> payload) -> bool;
// Pops the next payload if available.
// Pops the next unread payload; false only when none remains.
[[nodiscard]] auto pop(std::vector<std::uint8_t>& payload) -> bool;
private:
@@ -1,5 +1,6 @@
#include "shm_ring.hpp"
#include <algorithm>
#include <atomic>
#include <chrono>
#include <cerrno>
@@ -220,41 +221,43 @@ auto ShmRing::pop(std::vector<std::uint8_t>& payload) -> bool {
throw std::runtime_error("Ring is not open");
}
const auto read_seq = header_->read_seq.load(std::memory_order_relaxed);
const auto write_seq = header_->write_seq.load(std::memory_order_acquire);
if (read_seq >= write_seq) {
return false;
while (true) {
const auto read_seq = header_->read_seq.load(std::memory_order_relaxed);
const auto write_seq = header_->write_seq.load(std::memory_order_acquire);
if (read_seq >= write_seq) {
return false;
}
// A lapped, torn or corrupt slot is skipped with the backlog behind the newest
// payload, which is read next (latest-wins); a bad slot never stops the consumer.
const auto resync = std::max(read_seq + 1U, write_seq - 1U);
auto* slot = slot_header(read_seq);
if (std::atomic_ref(slot->sequence).load(std::memory_order_acquire) != read_seq + 1U) {
advance_read_seq(resync); // Overwritten before this read (lapped).
continue;
}
const auto payload_size = slot->payload_size;
if (payload_size > header_->slot_size_bytes) {
advance_read_seq(resync);
continue;
}
std::atomic_thread_fence(std::memory_order_acquire);
payload.resize(payload_size);
std::memcpy(payload.data(), slot_payload(slot), payload_size);
// Seqlock verify: if the slot sequence changed during the copy, the producer
// lapped us mid-read and the payload is torn.
std::atomic_thread_fence(std::memory_order_acquire);
if (std::atomic_ref(slot->sequence).load(std::memory_order_acquire) != read_seq + 1U) {
advance_read_seq(resync);
continue;
}
advance_read_seq(read_seq + 1U);
return true;
}
auto* slot = slot_header(read_seq);
if (std::atomic_ref(slot->sequence).load(std::memory_order_acquire) != read_seq + 1U) {
// Slot not published for this seq, or already overwritten (lapped). Resync.
advance_read_seq(write_seq);
return false;
}
const auto payload_size = slot->payload_size;
if (payload_size > header_->slot_size_bytes) {
// Corrupt/torn slot: skip it (resync) rather than throw — a single bad slot
// must never abort the long-running consumer.
advance_read_seq(write_seq);
return false;
}
std::atomic_thread_fence(std::memory_order_acquire);
payload.resize(payload_size);
std::memcpy(payload.data(), slot_payload(slot), payload_size);
// Seqlock verify: if the slot sequence changed during the copy, the producer
// lapped us mid-read and the payload is torn — discard and resync.
std::atomic_thread_fence(std::memory_order_acquire);
if (std::atomic_ref(slot->sequence).load(std::memory_order_acquire) != read_seq + 1U) {
advance_read_seq(write_seq);
return false;
}
advance_read_seq(read_seq + 1U);
return true;
}
void ShmRing::advance_read_seq(std::uint64_t target) {