/workspaces/astro/sol3-sdk/cpp/sol3/core/seq_ring.h Source File

Space-ng SDK: /workspaces/astro/sol3-sdk/cpp/sol3/core/seq_ring.h Source File
Space-ng SDK
seq_ring.h
Go to the documentation of this file.
1 // Copyright (c) Space-ng, inc. All rights reserved.
2 
3 // https://en.wikipedia.org/wiki/Seqlock
4 #pragma once
6 
7 #include <flatbuffers/stl_emulation.h>
8 
9 #include <atomic>
10 #include <chrono>
11 #include <cstddef>
12 #include <cstdint>
13 #include <cstdlib>
14 #include <cstring>
15 #include <vector>
16 
17 namespace sol3::core {
18 
19 size_t constexpr kCacheLineSize = 64;
20 
21 void* checkAlignedAs(void* data, size_t alignment);
22 
23 void const* checkAlignedAs(void const* data, size_t alignment);
24 
25 size_t checkSize(size_t size, size_t min_size);
26 
27 std::size_t alignUp(std::size_t v, std::size_t a);
28 
40 void atomicStoreMemcpy(void* dst, void const* src, size_t bytes);
41 
53 void atomicLoadMemcpy(void* dst, void const* src, size_t bytes);
54 
55 struct alignas(kCacheLineSize) SeqRingSlotHeader {
58  alignas(kCacheLineSize) std::atomic<uint64_t> seq;
59  uint32_t slot_type;
60  uint64_t max_size;
61  std::atomic<uint64_t> size;
62 };
63 
64 struct alignas(kCacheLineSize) SeqRingHeader {
65  alignas(kCacheLineSize) std::atomic<uint64_t> head_seq;
66  std::atomic<uint64_t> head_gen;
67  uint32_t slot_type;
68  uint64_t slot_count;
69  uint64_t slot_size;
70 };
71 
74  public:
75  SeqRingSlotView() = default;
77  SeqRingSlotView(SeqRingSlotHeader const* header, size_t seq);
78 
82  size_t copyTo(void* dest, std::chrono::steady_clock::duration time_out) const;
83 
85  size_t readInto(
86  IStreamWriter& stream,
87  std::chrono::steady_clock::duration time_out) const;
88 
90  size_t maxSize() const;
91 
93  bool dirty(std::memory_order order = std::memory_order_seq_cst) const;
94 
96  uint64_t seq() const;
97 
99  uint32_t slotType() const;
100 
101  private:
102  size_t size() const;
103 
104  uint8_t const* data() const;
105 
106  SeqRingSlotHeader const* header_ = nullptr;
107  uint64_t seq_ = 0;
108 };
109 
121  public:
123  static size_t minDataSize(size_t n_slots, size_t slot_size);
124 
130  uint32_t slot_type,
131  void* data,
132  size_t data_size,
133  size_t n_slots,
134  size_t slot_size);
135 
138  uint64_t write(
139  void const* header_data,
140  size_t header_size,
141  void const* payload_data,
142  size_t payload_size);
143 
146  uint64_t head() const;
147 
155  flatbuffers::span<uint8_t const> slotSpan(uint64_t seq) const;
156 
158  size_t slotCount() const;
159 
161  size_t slotSize() const;
162 
165  uint32_t slotType() const;
166 
167  private:
168  void* data_;
169  size_t data_size_;
170  SeqRingHeader* header_;
171  std::vector<SeqRingSlotHeader*> slot_headers_;
172 };
173 
177  public:
178  SeqRingReader() = default;
180  SeqRingReader(void const* data, size_t data_size);
181 
185  uint64_t head() const;
186 
189  SeqRingSlotView slot(size_t seq) const;
190 
192  size_t slotCount() const;
194  size_t slotSize() const;
195 
198  uint32_t slotType() const;
199 
202  flatbuffers::span<uint8_t const> trailerSpan() const;
203 
204  private:
205  void const* data_ = nullptr;
206  size_t data_size_ = 0;
207  SeqRingHeader const* header_ = nullptr;
208  std::vector<SeqRingSlotHeader const*> slot_headers_;
209 };
210 
211 } // namespace sol3::core
Minimal append-only byte sink for streaming writes.
Definition: stream_writer.h:9
Definition: seq_ring.h:176
size_t slotCount() const
Number of slots.
SeqRingReader(void const *data, size_t data_size)
Initializes the reader with a read only memory range.
size_t slotSize() const
Size in bytes of each slot.
SeqRingSlotView slot(size_t seq) const
uint64_t head() const
uint32_t slotType() const
flatbuffers::span< uint8_t const > trailerSpan() const
A read only view of a specific seq ring buffer slot.
Definition: seq_ring.h:73
SeqRingSlotView(SeqRingSlotHeader const *header, size_t seq)
This is typically constructed by SeqRingReader.
uint64_t seq() const
The sequence number that this view refers to.
size_t copyTo(void *dest, std::chrono::steady_clock::duration time_out) const
size_t maxSize() const
Maximum size in bytes of the slot.
size_t readInto(IStreamWriter &stream, std::chrono::steady_clock::duration time_out) const
Copy into an append-only stream. Returns bytes written, 0 on timeout.
uint32_t slotType() const
The type of the underlying slot data.
bool dirty(std::memory_order order=std::memory_order_seq_cst) const
Is the slot considered dirty?
Definition: seq_ring.h:120
static size_t minDataSize(size_t n_slots, size_t slot_size)
Minimum backing data size to hold n_slots of slot_size bytes.
SeqRingWriter(uint32_t slot_type, void *data, size_t data_size, size_t n_slots, size_t slot_size)
flatbuffers::span< uint8_t const > slotSpan(uint64_t seq) const
size_t slotCount() const
Number of slots.
uint32_t slotType() const
size_t slotSize() const
Size in bytes of each slot.
uint64_t head() const
uint64_t write(void const *header_data, size_t header_size, void const *payload_data, size_t payload_size)
Definition: any_message_input.h:15
void atomicStoreMemcpy(void *dst, void const *src, size_t bytes)
size_t checkSize(size_t size, size_t min_size)
void * checkAlignedAs(void *data, size_t alignment)
void atomicLoadMemcpy(void *dst, void const *src, size_t bytes)
std::size_t alignUp(std::size_t v, std::size_t a)
constexpr size_t kCacheLineSize
Definition: seq_ring.h:19
Definition: seq_ring.h:64
uint32_t slot_type
Definition: seq_ring.h:67
uint64_t slot_size
Definition: seq_ring.h:69
std::atomic< uint64_t > head_gen
Definition: seq_ring.h:66
uint64_t slot_count
Definition: seq_ring.h:68
Definition: seq_ring.h:55
uint64_t max_size
Definition: seq_ring.h:60
uint32_t slot_type
Definition: seq_ring.h:59
std::atomic< uint64_t > size
Definition: seq_ring.h:61