Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
shm_common.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <cassert>
5#include <cstring>
6#include <iostream>
7#include <span>
8#include <stdexcept>
9
10namespace bb::ipc {
11
12inline bool ring_send_msg(SpscShm& ring, const void* data, size_t len, uint64_t timeout_ns)
13{
14 // Prevent sending messages larger than half the ring buffer capacity.
15 // This simplifies wrap-around logic.
16 if (len > ring.capacity() / 2 - 4) {
17 throw std::runtime_error(
18 "ring_send_msg: message too large for ring buffer, must be <= half capacity minus 4 bytes");
19 }
20
21 // Atomic send: claim space for entire message (length + data)
22 size_t total_size = 4 + len;
23 void* buf = ring.claim(total_size, static_cast<uint32_t>(timeout_ns));
24 if (buf == nullptr) {
25 return false; // Timeout or no space - nothing published yet (atomic failure)
26 }
27
28 // Write length prefix and message data together
29 auto len_u32 = static_cast<uint32_t>(len);
30 std::memcpy(buf, &len_u32, 4);
31 std::memcpy(static_cast<uint8_t*>(buf) + 4, data, len);
32
33 // Publish entire message atomically
34 ring.publish(total_size);
35
36 return true;
37}
38
39inline std::span<const uint8_t> ring_receive_msg(SpscShm& ring, uint64_t timeout_ns)
40{
41 // Peek the length prefix (4 bytes)
42 void* len_ptr = ring.peek(4, static_cast<uint32_t>(timeout_ns));
43 if (len_ptr == nullptr) {
44 return {}; // Timeout
45 }
46
47 // Read message length
48 uint32_t msg_len = 0;
49 std::memcpy(&msg_len, len_ptr, 4);
50
51 // Now peek the message data
52 void* msg_ptr = ring.peek(4 + msg_len, static_cast<uint32_t>(timeout_ns));
53 if (msg_ptr == nullptr) {
54 return {}; // Timeout
55 }
56
57 // Return span directly into ring buffer (zero-copy!)
58 return std::span<const uint8_t>(static_cast<const uint8_t*>(msg_ptr) + 4, msg_len);
59}
60
61} // namespace bb::ipc
Lock-free single-producer single-consumer shared memory ring buffer.
Definition spsc_shm.hpp:70
void * peek(size_t want, uint32_t timeout_ns)
Peek contiguous readable region (blocks until available)
Definition spsc_shm.cpp:254
uint64_t capacity() const
Definition spsc_shm.hpp:105
void * claim(size_t want, uint32_t timeout_ns)
Claim contiguous space in the ring buffer (blocks until available)
Definition spsc_shm.cpp:204
void publish(size_t n)
Publish n bytes previously claimed.
Definition spsc_shm.cpp:227
const std::vector< MemoryValue > data
uint8_t const * buf
Definition data_store.hpp:9
bool ring_send_msg(SpscShm &ring, const void *data, size_t len, uint64_t timeout_ns)
std::span< const uint8_t > ring_receive_msg(SpscShm &ring, uint64_t timeout_ns)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
uint8_t len
Single-producer/single-consumer shared-memory ring buffer (Linux, x86-64 optimized)