byteor_abi/layouts/
sequenced_slots.rs

1use indexbus_abi::layouts::{SequencerGatingCell, SlotPoolLayout};
2use indexbus_abi::{
3    caps as ib_caps, flags as ib_flags, IndexbusAtomicU32, IndexbusAtomicU64, LayoutHeader,
4};
5
6use crate::header::{caps, flags};
7
8/// Concrete v1 consumer count used by `SequencedSlotsLayout4`.
9pub const BYTEOR_SEQUENCED_SLOTS_CONSUMERS_DEFAULT: usize = 4;
10
11/// ByteOr sequenced-slots region: sequencer + slot pool + a fixed ring of slot indices.
12///
13/// This region is the ABI substrate for pipeline lanes that need:
14/// - strict per-lane ordering (via a sequencer cursor), and
15/// - payload storage in shared memory (via fixed-size slots), and
16/// - replay by sequence within the bounded ring window.
17///
18/// v1 notes:
19/// - Capacity is fixed by the IndexBus ABI constant `INDEXBUS_QUEUE_CAPACITY`.
20/// - Each published sequence `seq` maps to `ring[seq % INDEXBUS_QUEUE_CAPACITY]`.
21/// - Producers must not wrap past the minimum gating sequence (Disruptor-style).
22#[repr(C, align(64))]
23pub struct SequencedSlotsLayout<const N: usize> {
24    /// Common region header (magic/version/capabilities/layout size).
25    pub header: LayoutHeader,
26
27    /// 0 = uninitialized, 1 = initializing, 2 = initialized
28    pub initialized: IndexbusAtomicU32,
29    /// Padding (reserved).
30    pub _pad0: u32,
31
32    /// Pad to 64 so the first counter starts at offset 64.
33    pub _pad_to_64: [u8; 40],
34
35    /// Producer cursor (monotonic sequence).
36    pub cursor: IndexbusAtomicU64,
37    /// Padding to keep the cursor in its own cache line.
38    pub _pad_cursor: [u8; 56],
39
40    /// Per-consumer gating sequences.
41    pub gating: [SequencerGatingCell; N],
42
43    /// Slot pool storing payload bytes.
44    pub slot_pool: SlotPoolLayout,
45
46    /// Ring mapping `seq -> slot index`.
47    ///
48    /// Entries use `INDEXBUS_EMPTY_FREE_U32` as the "uninitialized" sentinel.
49    pub ring: [IndexbusAtomicU32; indexbus_abi::INDEXBUS_QUEUE_CAPACITY],
50}
51
52impl<const N: usize> SequencedSlotsLayout<N> {
53    /// Capabilities required for this region to be considered compatible.
54    pub const REQUIRED_CAPS: u32 =
55        ib_caps::INDEXBUS_CAP_SUPPORTS_EVENTS | caps::BYTEOR_CAP_SUPPORTS_SEQUENCED_SLOTS;
56
57    /// Region kind discriminator stored in `LayoutHeader.flags`.
58    pub const REGION_KIND: u16 = flags::BYTEOR_REGION_KIND_SEQUENCED_SLOTS;
59
60    /// Mask for the low 8 bits containing the region kind discriminator.
61    pub const REGION_KIND_MASK: u16 = ib_flags::INDEXBUS_FLAGS_REGION_KIND_MASK;
62
63    /// Sentinel stored in `ring` entries before a slot is published.
64    pub const EMPTY_RING: u32 = indexbus_abi::INDEXBUS_EMPTY_FREE_U32;
65}
66
67/// Concrete v1 sequenced-slots layout for `N=4`.
68///
69/// This is a convenient "known size" layout for tools and smoke tests.
70#[repr(C, align(64))]
71pub struct SequencedSlotsLayout4 {
72    /// Common region header (magic/version/capabilities/layout size).
73    pub header: LayoutHeader,
74
75    /// 0 = uninitialized, 1 = initializing, 2 = initialized
76    pub initialized: IndexbusAtomicU32,
77    /// Padding (reserved).
78    pub _pad0: u32,
79
80    /// Pad to 64 so the first counter starts at offset 64.
81    pub _pad_to_64: [u8; 40],
82
83    /// Producer cursor (monotonic sequence).
84    pub cursor: IndexbusAtomicU64,
85    /// Padding to keep the cursor in its own cache line.
86    pub _pad_cursor: [u8; 56],
87
88    /// Per-consumer gating sequences.
89    pub gating: [SequencerGatingCell; BYTEOR_SEQUENCED_SLOTS_CONSUMERS_DEFAULT],
90
91    /// Slot pool storing payload bytes.
92    pub slot_pool: SlotPoolLayout,
93
94    /// Ring mapping `seq -> slot index`.
95    pub ring: [IndexbusAtomicU32; indexbus_abi::INDEXBUS_QUEUE_CAPACITY],
96}
97
98impl SequencedSlotsLayout4 {
99    /// Capabilities required for this region to be considered compatible.
100    pub const REQUIRED_CAPS: u32 =
101        SequencedSlotsLayout::<BYTEOR_SEQUENCED_SLOTS_CONSUMERS_DEFAULT>::REQUIRED_CAPS;
102
103    /// Region kind discriminator stored in `LayoutHeader.flags`.
104    pub const REGION_KIND: u16 =
105        SequencedSlotsLayout::<BYTEOR_SEQUENCED_SLOTS_CONSUMERS_DEFAULT>::REGION_KIND;
106
107    /// Mask for the low 8 bits containing the region kind discriminator.
108    pub const REGION_KIND_MASK: u16 =
109        SequencedSlotsLayout::<BYTEOR_SEQUENCED_SLOTS_CONSUMERS_DEFAULT>::REGION_KIND_MASK;
110
111    /// Sentinel stored in `ring` entries before a slot is published.
112    pub const EMPTY_RING: u32 =
113        SequencedSlotsLayout::<BYTEOR_SEQUENCED_SLOTS_CONSUMERS_DEFAULT>::EMPTY_RING;
114}