Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
spsc_shm.hpp
Go to the documentation of this file.
1
11#pragma once
12
13#include <array>
14#include <atomic>
15#include <cstddef>
16#include <cstdint>
17#include <string>
18
19namespace bb::ipc {
20
21constexpr size_t SPSC_CACHELINE = 64;
22
28struct alignas(SPSC_CACHELINE) SpscCtrl {
29 // Producer-owned (written by producer, read by consumer)
30 alignas(SPSC_CACHELINE) std::atomic<uint64_t> head; // bytes written
31 uint64_t wrap_head; // Head value when last message wrapped (UINT64_MAX = no wrap), synchronized by head
32 std::atomic<bool> producer_blocked; // Written by producer in wait_for_space()
33 std::array<char, SPSC_CACHELINE - sizeof(head) - sizeof(wrap_head) - sizeof(producer_blocked)> _pad0;
34
35 // Consumer-owned (written by consumer, read by producer)
36 alignas(SPSC_CACHELINE) std::atomic<uint64_t> tail; // bytes consumed
37 std::atomic<bool> consumer_blocked; // Written by consumer in wait_for_data()
38 std::array<char, SPSC_CACHELINE - sizeof(tail) - sizeof(consumer_blocked)> _pad1;
39
40 // Immutable capacity information
41 alignas(SPSC_CACHELINE) uint64_t capacity; // power of two
42 alignas(SPSC_CACHELINE) uint64_t mask; // capacity - 1
43
44 // uint8_t buffer[capacity] follows in memory...
45};
46
47static_assert(alignof(SpscCtrl) == SPSC_CACHELINE, "SpscCtrl alignment");
48static_assert(sizeof(SpscCtrl) % SPSC_CACHELINE == 0, "SpscCtrl size multiple of cache line");
49
70class SpscShm {
71 public:
78 static SpscShm create(const std::string& name, size_t min_capacity);
79
85 static SpscShm connect(const std::string& name);
86
92 static bool unlink(const std::string& name);
93
94 // Move-only (no copy)
95 SpscShm(SpscShm&& other) noexcept;
96 SpscShm& operator=(SpscShm&& other) noexcept;
97 SpscShm(const SpscShm&) = delete;
98 SpscShm& operator=(const SpscShm&) = delete;
99
100 ~SpscShm();
101
102 // Introspection
103 uint64_t available() const; // bytes ready to read
104
105 uint64_t capacity() const { return ctrl_->capacity; }
106
118 void* claim(size_t want, uint32_t timeout_ns);
119
127 void publish(size_t n);
128
140 void* peek(size_t want, uint32_t timeout_ns);
141
149 void release(size_t n);
150
157 void wakeup_all();
158
159 bool wait_for_data(size_t need, uint32_t spin_ns);
160 bool wait_for_space(size_t need, uint32_t spin_ns);
161
166 void debug_dump(const char* prefix) const;
167
168 private:
169 // Private constructor for create/connect factories
170 SpscShm(int fd, size_t map_len, SpscCtrl* ctrl, uint8_t* buf);
171
172 int fd_ = -1;
173 size_t map_len_ = 0;
174 SpscCtrl* ctrl_ = nullptr;
175 uint8_t* buf_ = nullptr;
176 bool previous_had_data_ = false; // Adaptive spinning: consumer only spins if previous call found data
177 bool previous_had_space_ = false; // Adaptive spinning: producer only spins if previous call found space
178};
179
180} // namespace bb::ipc
Lock-free single-producer single-consumer shared memory ring buffer.
Definition spsc_shm.hpp:70
SpscShm(const SpscShm &)=delete
uint64_t capacity() const
Definition spsc_shm.hpp:105
SpscShm & operator=(const SpscShm &)=delete
uint8_t const * buf
Definition data_store.hpp:9
constexpr size_t SPSC_CACHELINE
Definition spsc_shm.hpp:21
Control structure for SPSC ring buffer.
Definition spsc_shm.hpp:28
std::atomic< bool > consumer_blocked
Definition spsc_shm.hpp:37
std::array< char, SPSC_CACHELINE - sizeof(tail) - sizeof(consumer_blocked)> _pad1
Definition spsc_shm.hpp:38
std::atomic< bool > producer_blocked
Definition spsc_shm.hpp:32
uint64_t wrap_head
Definition spsc_shm.hpp:31