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}