Skip to main content

dope_core/driver/settings/demands/
mod.rs

1use o3::depot::capacity;
2
3use crate::{
4    driver::{route::table::conn, settings, settings::errors},
5    io::transfer,
6};
7
8pub mod slots;
9
10#[derive(Clone, Copy, Default, Eq, PartialEq)]
11#[repr(C)]
12pub struct Files {
13    accepted: Accept,
14    outbound: Outbound,
15}
16
17#[derive(Clone, Copy, Default, Eq, PartialEq)]
18#[repr(transparent)]
19pub struct Accept(u32);
20
21#[derive(Clone, Copy, Default, Eq, PartialEq)]
22#[repr(transparent)]
23pub struct Outbound(u32);
24
25impl Files {
26    pub const ZERO: Self = Self::new(Accept::ZERO, Outbound::ZERO);
27
28    pub const fn new(accepted: Accept, outbound: Outbound) -> Self {
29        Self { accepted, outbound }
30    }
31
32    pub const fn accept(accepted: Accept) -> Self {
33        Self::new(accepted, Outbound::ZERO)
34    }
35
36    pub const fn only_out(outbound: Outbound) -> Self {
37        Self::new(Accept::ZERO, outbound)
38    }
39
40    pub const fn accepted(self) -> Accept {
41        self.accepted
42    }
43
44    pub const fn outbound(self) -> Outbound {
45        self.outbound
46    }
47
48    pub(in crate::driver::settings) fn merge(self, next: Self) -> Result<Self, errors::Claim> {
49        let current = self.accepted.get();
50        let added = next.accepted.get();
51        let accepted = Accept(
52            current
53                .checked_add(added)
54                .ok_or(errors::Claim::AcceptedDescriptorsOverflow { current, added })?,
55        );
56        let current = self.outbound.get();
57        let added = next.outbound.get();
58        let outbound = Outbound(
59            current
60                .checked_add(added)
61                .ok_or(errors::Claim::OutboundDescriptorsOverflow { current, added })?,
62        );
63        Ok(Self::new(accepted, outbound))
64    }
65}
66
67impl Accept {
68    pub const ZERO: Self = Self(0);
69    pub(in crate::driver::settings) const fn get(self) -> u32 {
70        self.0
71    }
72}
73
74impl From<slots::Slots> for Accept {
75    fn from(slots: slots::Slots) -> Self {
76        Self(slots.raw())
77    }
78}
79
80impl From<conn::Capacity> for Accept {
81    fn from(capacity: conn::Capacity) -> Self {
82        Self(capacity.raw())
83    }
84}
85
86impl Outbound {
87    pub const ZERO: Self = Self(0);
88    pub const fn fixed<const VALUE: u32>() -> Self {
89        Self(VALUE)
90    }
91    pub(in crate::driver::settings) const fn get(self) -> u32 {
92        self.0
93    }
94
95    pub const fn scale<const FACTOR: u32>(capacity: conn::Capacity) -> Self {
96        Self(capacity.scale::<FACTOR>().raw())
97    }
98}
99
100impl TryFrom<usize> for Accept {
101    type Error = Overflow;
102    fn try_from(value: usize) -> Result<Self, Self::Error> {
103        Ok(Self(capacity::Count::try_from(value)?.raw()))
104    }
105}
106
107impl TryFrom<usize> for Outbound {
108    type Error = Overflow;
109    fn try_from(value: usize) -> Result<Self, Self::Error> {
110        Ok(Self(capacity::Count::try_from(value)?.raw()))
111    }
112}
113
114/// Additive receive-pool demand. Entries compose by addition while buffer
115/// length composes by maximum because every slot uses the largest framing.
116#[derive(Clone, Copy, Eq, PartialEq)]
117#[repr(C)]
118pub struct Receive {
119    entries: Entries,
120    buffer_len: transfer::Len,
121}
122
123/// Additive receive-slot demand representable by the claim accumulator.
124#[derive(Clone, Copy, Default, Eq, PartialEq)]
125#[repr(transparent)]
126pub struct Entries(u32);
127
128#[derive(Clone, Copy, Debug, Eq, PartialEq)]
129#[repr(transparent)]
130pub struct Overflow {
131    actual: usize,
132}
133
134#[derive(Clone, Copy, Default, Eq, PartialEq)]
135#[repr(transparent)]
136pub struct Submit(u32);
137
138/// Additive scheduler demand for ready and timer slots.
139#[derive(Clone, Copy, Default, Eq, PartialEq)]
140#[repr(C)]
141pub struct Schedule {
142    ready: slots::Slots,
143    timers: slots::Slots,
144}
145
146impl Receive {
147    pub const ZERO: Self = Self {
148        entries: Entries::ZERO,
149        buffer_len: transfer::Len::ZERO,
150    };
151
152    pub const fn new(entries: Entries, len: transfer::Len) -> Self {
153        Self {
154            entries,
155            buffer_len: len,
156        }
157    }
158
159    pub const fn entries(self) -> Entries {
160        self.entries
161    }
162
163    pub const fn buffer_len(self) -> transfer::Len {
164        self.buffer_len
165    }
166
167    pub(in crate::driver::settings) fn merge(self, next: Self) -> Result<Self, errors::Claim> {
168        let entries = self.entries.0.checked_add(next.entries.0).ok_or(
169            errors::Claim::ReceiveEntriesOverflow {
170                current: self.entries.0,
171                added: next.entries.0,
172            },
173        )?;
174        Ok(Self::new(
175            Entries(entries),
176            self.buffer_len.max(next.buffer_len),
177        ))
178    }
179}
180
181impl From<settings::Receive> for Receive {
182    fn from(layout: settings::Receive) -> Self {
183        Self::new(
184            Entries(u32::from(layout.entries())),
185            transfer::Len::from_nonzero(layout.buffer_len()),
186        )
187    }
188}
189
190impl From<settings::Datagram> for Receive {
191    fn from(layout: settings::Datagram) -> Self {
192        Self::new(
193            Entries(u32::from(layout.0.entries())),
194            transfer::Len::from_nonzero(layout.0.buffer_len()),
195        )
196    }
197}
198
199impl Entries {
200    pub const ZERO: Self = Self(0);
201
202    pub(in crate::driver::settings) const fn get(self) -> u32 {
203        self.0
204    }
205}
206
207impl From<capacity::Count> for Entries {
208    fn from(count: capacity::Count) -> Self {
209        Self(count.raw())
210    }
211}
212
213impl TryFrom<usize> for Entries {
214    type Error = Overflow;
215
216    fn try_from(value: usize) -> Result<Self, Self::Error> {
217        Ok(Self(capacity::Count::try_from(value)?.raw()))
218    }
219}
220
221impl From<capacity::Error> for Overflow {
222    fn from(error: capacity::Error) -> Self {
223        Self::new(error.requested())
224    }
225}
226
227impl Overflow {
228    pub(in crate::driver::settings) const fn new(actual: usize) -> Self {
229        Self { actual }
230    }
231}
232
233impl Default for Receive {
234    fn default() -> Self {
235        Self::ZERO
236    }
237}
238
239impl Submit {
240    pub(in crate::driver::settings) const fn get(self) -> u32 {
241        self.0
242    }
243}
244
245impl From<u32> for Submit {
246    fn from(value: u32) -> Self {
247        Self(value)
248    }
249}
250
251impl Schedule {
252    pub const ZERO: Self = Self::new(slots::Slots::ZERO, slots::Slots::ZERO);
253
254    pub const fn new(ready: slots::Slots, timers: slots::Slots) -> Self {
255        Self { ready, timers }
256    }
257
258    pub const fn fixed<const READY: u32, const TIMERS: u32>() -> Self {
259        Self::new(
260            slots::Slots::fixed::<READY>(),
261            slots::Slots::fixed::<TIMERS>(),
262        )
263    }
264
265    pub const fn ready(self) -> slots::Slots {
266        self.ready
267    }
268
269    pub const fn timers(self) -> slots::Slots {
270        self.timers
271    }
272
273    pub(in crate::driver::settings) fn merge(self, next: Self) -> Result<Self, errors::Claim> {
274        let ready = self
275            .ready
276            .checked_add(next.ready)
277            .map_err(errors::Claim::SchedulerReadyOverflow)?;
278        let timers = self
279            .timers
280            .checked_add(next.timers)
281            .map_err(errors::Claim::SchedulerTimersOverflow)?;
282        Ok(Self::new(ready, timers))
283    }
284}
285
286const _: () = {
287    assert!(core::mem::size_of::<Files>() == 2 * core::mem::size_of::<u32>());
288    assert!(core::mem::size_of::<Accept>() == core::mem::size_of::<u32>());
289    assert!(core::mem::size_of::<Outbound>() == core::mem::size_of::<u32>());
290    assert!(core::mem::size_of::<Receive>() == 2 * core::mem::size_of::<u32>());
291    assert!(core::mem::size_of::<Entries>() == core::mem::size_of::<u32>());
292    assert!(core::mem::size_of::<Submit>() == core::mem::size_of::<u32>());
293    assert!(core::mem::size_of::<Schedule>() == 2 * core::mem::size_of::<u32>());
294};