Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
mpsc_shm_client.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "ipc_client.hpp"
4#include "shm/mpsc_shm.hpp"
5#include "shm/spsc_shm.hpp"
6#include "shm_common.hpp"
7#include <cassert>
8#include <cstdint>
9#include <cstring>
10#include <optional>
11#include <string>
12#include <utility>
13
14namespace bb::ipc {
15
22class MpscShmClient : public IpcClient {
23 public:
24 MpscShmClient(std::string base_name, size_t client_id)
25 : base_name_(std::move(base_name))
26 , client_id_(client_id)
27 {}
28
29 ~MpscShmClient() override = default;
30
31 // Non-copyable, non-movable
32 MpscShmClient(const MpscShmClient&) = delete;
36
37 bool connect() override
38 {
39 if (producer_.has_value()) {
40 return true; // Already connected
41 }
42
43 try {
44 // Connect as producer to the MPSC request system
46
47 // Connect to our dedicated SPSC response ring
48 std::string resp_name = base_name_ + "_resp_" + std::to_string(client_id_);
50
51 return true;
52 } catch (...) {
53 producer_.reset();
54 response_ring_.reset();
55 return false;
56 }
57 }
58
59 bool send(const void* data, size_t len, uint64_t timeout_ns) override
60 {
61 if (!producer_.has_value()) {
62 return false;
63 }
64
65 // Claim space for length prefix + data
66 size_t total_size = sizeof(uint32_t) + len;
67 void* buf = producer_->claim(total_size, static_cast<uint32_t>(timeout_ns));
68 if (buf == nullptr) {
69 return false;
70 }
71
72 // Write length prefix + data
73 auto len_u32 = static_cast<uint32_t>(len);
74 std::memcpy(buf, &len_u32, sizeof(uint32_t));
75 std::memcpy(static_cast<uint8_t*>(buf) + sizeof(uint32_t), data, len);
76
77 // Publish (rings doorbell to wake server)
78 producer_->publish(total_size);
79 return true;
80 }
81
82 std::span<const uint8_t> receive(uint64_t timeout_ns) override
83 {
84 if (!response_ring_.has_value()) {
85 return {};
86 }
87 return ring_receive_msg(response_ring_.value(), timeout_ns);
88 }
89
90 void release(size_t message_size) override
91 {
92 if (!response_ring_.has_value()) {
93 return;
94 }
95 response_ring_->release(sizeof(uint32_t) + message_size);
96 }
97
98 void close() override
99 {
100 producer_.reset();
101 response_ring_.reset();
102 }
103
104 private:
105 std::string base_name_;
109};
110
111} // namespace bb::ipc
Abstract interface for IPC client.
static MpscProducer connect(const std::string &name, size_t producer_id)
Connect to MPSC system as a producer.
Definition mpsc_shm.cpp:333
IPC client for multi-client shared memory server.
std::optional< MpscProducer > producer_
MpscShmClient(MpscShmClient &&)=delete
MpscShmClient & operator=(const MpscShmClient &)=delete
MpscShmClient(const MpscShmClient &)=delete
std::span< const uint8_t > receive(uint64_t timeout_ns) override
Receive a message from the server (zero-copy for shared memory)
bool send(const void *data, size_t len, uint64_t timeout_ns) override
Send a message to the server.
std::optional< SpscShm > response_ring_
~MpscShmClient() override=default
void close() override
Close the connection.
MpscShmClient(std::string base_name, size_t client_id)
MpscShmClient & operator=(MpscShmClient &&)=delete
bool connect() override
Connect to the server.
void release(size_t message_size) override
Release the previously received message.
static SpscShm connect(const std::string &name)
Connect to existing SPSC ring buffer.
Definition spsc_shm.cpp:157
const std::vector< MemoryValue > data
Multi-Producer Single-Consumer via SPSC rings + doorbell futex.
std::span< const uint8_t > ring_receive_msg(SpscShm &ring, uint64_t timeout_ns)
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
uint8_t len
Single-producer/single-consumer shared-memory ring buffer (Linux, x86-64 optimized)