Skip to main content

dope_core/driver/route/
mod.rs

1pub mod indices;
2use core::{hash, marker, mem, num};
3
4use indices::SlotIndex;
5pub use o3::base::num::Epoch;
6pub use token::Token;
7pub(crate) use token::{Brand, OutboundKey};
8
9use crate::driver::route;
10
11pub mod lease;
12pub(in crate::driver) mod queues;
13pub mod raw;
14pub mod table;
15mod token;
16
17pub(crate) const FRAMEWORK: u8 = 255;
18pub(crate) const CAPACITY: usize = u8::MAX as usize + 1;
19
20pub(crate) const SHIFT: u32 = 56;
21pub(crate) const KIND_SHIFT: u32 = 48;
22pub const SLOT_BITS: u32 = 24;
23pub const SLOT_MASK: u64 = (1 << SLOT_BITS) - 1;
24pub(crate) const AUX_SHIFT: u32 = SLOT_BITS;
25pub(crate) const AUX_BITS: u32 = KIND_SHIFT - AUX_SHIFT;
26pub(crate) const AUX_VALUE_MASK: u32 = (1 << AUX_BITS) - 1;
27pub(crate) const AUX_MASK: u64 = (AUX_VALUE_MASK as u64) << AUX_SHIFT;
28
29/// A validated application route identity. The framework route cannot be
30/// constructed as an `Id`.
31#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
32#[repr(transparent)]
33pub struct Id(u8);
34
35/// The route namespace observed on a token or event.
36#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
37#[repr(transparent)]
38pub struct Route(u8);
39
40impl Id {
41    pub const fn fixed<const ID: u8>() -> Self {
42        const { assert!(ID != FRAMEWORK, "framework route is reserved") };
43        Self(ID)
44    }
45
46    /// Exact numeric identity, for hash domains and retained diagnostics.
47    pub const fn raw(self) -> u8 {
48        self.0
49    }
50
51    pub(crate) const fn into_route(self) -> Route {
52        Route(self.0)
53    }
54}
55
56impl Route {
57    pub(crate) const FRAMEWORK: Self = Self(FRAMEWORK);
58
59    pub(crate) const fn app(self) -> Option<Id> {
60        if self.is_framework() {
61            None
62        } else {
63            Some(Id(self.0))
64        }
65    }
66
67    pub(crate) const fn from_bits(raw: u8) -> Self {
68        Self(raw)
69    }
70
71    pub const fn is_framework(self) -> bool {
72        self.0 == FRAMEWORK
73    }
74
75    pub(crate) const fn raw(self) -> u8 {
76        self.0
77    }
78}
79
80impl From<Id> for Route {
81    fn from(id: Id) -> Self {
82        Self(id.raw())
83    }
84}
85
86impl TryFrom<Route> for Id {
87    type Error = Route;
88
89    fn try_from(route: Route) -> Result<Self, Self::Error> {
90        route.app().ok_or(route)
91    }
92}
93
94/// A route tag carrying its operation class as a type.
95///
96///
97#[derive(Clone, Copy, Debug)]
98pub struct KeyTag<const ROUTE: u8, C: kind::Class = kind::Any>(marker::PhantomData<C>);
99
100/// A framework-owned route tag for one registered operation class.
101#[derive(Clone, Copy)]
102pub struct FrameworkTag<C: kind::Class>(marker::PhantomData<C>);
103
104/// A route tag carries its identity through every invariant branded target.
105pub trait Tag: Copy {
106    const ROUTE: Route;
107    type Class: kind::Class;
108}
109
110/// Proves that a target tag may be materialized as one operation class.
111pub trait Select<C: kind::Class>: Tag {}
112
113/// A route tag proven to belong to the application namespace.
114pub trait App: Tag + kind::Sealed {
115    const ID: Id;
116}
117
118/// One application route identity usable in every operation class.
119///
120/// It carries [`Select`]'s class selection instead of a `const ID: u8` brand,
121/// so it adds no authority the class marker withheld.
122pub trait Identity:
123    App<Class = kind::Any>
124    + Eq
125    + hash::Hash
126    + Materialize<kind::Accept>
127    + Materialize<kind::Recv>
128    + Materialize<kind::Send>
129    + Materialize<kind::Socket>
130    + Materialize<kind::Connect>
131    + Materialize<kind::Shutdown>
132    + Materialize<kind::Open>
133    + Materialize<kind::OneShot>
134    + Materialize<kind::TaskQueue>
135    + Materialize<kind::Tuning>
136    + Materialize<kind::Write>
137    + Materialize<kind::Sync>
138    + Materialize<kind::Read>
139{
140}
141
142/// One route identity materialized as a specific operation class.
143///
144/// The class a route is used in is part of the tag's type, so naming it is a
145/// type-level projection this trait carries for an unspecified class.
146pub trait Materialize<C: kind::Class>: Tag<Class = kind::Any> {
147    type With: App<Class = C> + Select<C>;
148}
149
150impl<const ROUTE: u8> Identity for KeyTag<ROUTE, kind::Any> {}
151
152impl<const ROUTE: u8, C: kind::Class> Materialize<C> for KeyTag<ROUTE, kind::Any>
153where
154    KeyTag<ROUTE, C>: App<Class = C> + Select<C>,
155{
156    type With = KeyTag<ROUTE, C>;
157}
158
159/// A tag carries only its route and class as types, so every value of one tag
160/// type is the same identity and hashes by that route.
161impl<const ROUTE: u8, C: kind::Class> PartialEq for KeyTag<ROUTE, C> {
162    fn eq(&self, _: &Self) -> bool {
163        true
164    }
165}
166
167impl<const ROUTE: u8, C: kind::Class> Eq for KeyTag<ROUTE, C> {}
168
169impl<const ROUTE: u8, C: kind::Class> hash::Hash for KeyTag<ROUTE, C> {
170    fn hash<H: hash::Hasher>(&self, state: &mut H) {
171        state.write_u8(ROUTE);
172    }
173}
174
175impl<const ROUTE: u8, C: kind::Class> Tag for KeyTag<ROUTE, C> {
176    const ROUTE: Route = Id::fixed::<ROUTE>().into_route();
177    type Class = C;
178}
179
180impl<const ROUTE: u8, C: kind::Class> App for KeyTag<ROUTE, C> {
181    const ID: Id = Id::fixed::<ROUTE>();
182}
183
184impl<const ROUTE: u8, C: kind::Class> kind::Sealed for KeyTag<ROUTE, C> {}
185
186impl<C: kind::Class> Tag for FrameworkTag<C> {
187    const ROUTE: Route = Route::FRAMEWORK;
188    type Class = C;
189}
190
191impl<T: Tag<Class = kind::Any>, C: kind::Class> Select<C> for T {}
192/// One operation identity branded by its driver lifetime and route.
193#[derive(Clone, Copy)]
194#[repr(transparent)]
195pub struct Operation<'d, T: Tag, C: kind::Class = <T as Tag>::Class> {
196    token: Token,
197    driver: Brand<'d, T>,
198    class: marker::PhantomData<C>,
199}
200
201impl<'d, T: Tag, C: kind::Class> Operation<'d, T, C> {
202    pub(super) const fn new(token: Token, driver: Brand<'d, T>) -> Self {
203        Self {
204            token,
205            driver,
206            class: marker::PhantomData,
207        }
208    }
209
210    pub fn matches(self, target: Erased<'d, C>) -> bool {
211        self.token == target.token
212    }
213
214    pub const fn parts(self) -> table::Parts<T> {
215        table::Parts::new(self.token.slot(), self.token.epoch())
216    }
217
218    pub const fn erase_route(self) -> Erased<'d, C> {
219        Erased::new(self.token, self.driver.driver).bind(kind::Witness(self.class))
220    }
221
222    pub(crate) const fn into_token(self) -> Token {
223        self.token
224    }
225}
226
227impl<T: Tag, C: kind::Class> PartialEq for Operation<'_, T, C> {
228    fn eq(&self, other: &Self) -> bool {
229        self.token == other.token
230    }
231}
232
233impl<T: Tag, C: kind::Class> Eq for Operation<'_, T, C> {}
234
235impl<T: Tag, C: kind::Class> hash::Hash for Operation<'_, T, C> {
236    fn hash<H: hash::Hasher>(&self, state: &mut H) {
237        self.token.hash(state);
238    }
239}
240
241/// Logical operation target with its native flight identity when submitted.
242#[derive(Clone, Copy)]
243#[repr(C)]
244pub struct Erased<'d, C: kind::Class> {
245    pub(in crate::driver) token: Token,
246    // Completion delivery preserves the already-admitted native identity even
247    // after its arena slot is released. Logical routing remains independent.
248    pub(in crate::driver) flight: Option<super::retained::flight::raw::Echo>,
249    pub(in crate::driver) driver: super::Invariant<'d>,
250    pub(in crate::driver) class: marker::PhantomData<C>,
251}
252
253impl<'d> Erased<'d, kind::Any> {
254    pub(in crate::driver) const fn new(token: Token, driver: super::Invariant<'d>) -> Self {
255        Self {
256            token,
257            flight: None,
258            driver,
259            class: marker::PhantomData,
260        }
261    }
262
263    pub(crate) const fn bind<C: kind::Class>(self, proof: kind::Witness<C>) -> Erased<'d, C> {
264        let kind::Witness(class) = proof;
265        Erased {
266            token: self.token,
267            flight: self.flight,
268            driver: self.driver,
269            class,
270        }
271    }
272}
273
274impl<'d, C: kind::Class> Erased<'d, C> {
275    pub fn matches(self, target: Self) -> bool {
276        self.token == target.token
277    }
278
279    pub(crate) fn matches_flight(self, target: Self) -> bool {
280        // The shared driver brand fixes the arena; an echo is never reused and
281        // identifies one immutable target.
282        self.flight.is_some() && self.flight == target.flight
283    }
284
285    pub const fn route(self) -> Route {
286        self.token.route()
287    }
288
289    pub const fn slot(self) -> SlotIndex {
290        self.token.slot()
291    }
292
293    pub const fn epoch(self) -> Epoch {
294        self.token.epoch()
295    }
296
297    pub(crate) const fn into_token(self) -> Token {
298        self.token
299    }
300}
301
302/// A class-typed operation that belongs to another route.
303pub struct Mismatch<'d, T: Tag, C: kind::Class> {
304    target: Erased<'d, C>,
305    tag: marker::PhantomData<T>,
306}
307
308impl<'d, T: Tag, C: kind::Class> Mismatch<'d, T, C> {
309    const fn new(target: Erased<'d, C>) -> Self {
310        Self {
311            target,
312            tag: marker::PhantomData,
313        }
314    }
315
316    pub fn into_target(self) -> Erased<'d, C> {
317        self.target
318    }
319}
320
321pub mod kind;
322
323pub const SHUTDOWN: Control = Control::new(<kind::Shutdown as kind::Class>::CODE, SlotIndex::ZERO);
324
325const _: () = {
326    assert!(
327        mem::size_of::<Erased<'static, kind::Send>>()
328            == mem::size_of::<Token>() + mem::size_of::<usize>()
329    );
330    assert!(mem::align_of::<Erased<'static, kind::Send>>() == mem::align_of::<Token>());
331    assert!(
332        mem::size_of::<Mismatch<'static, KeyTag<1>, kind::Send>>()
333            == mem::size_of::<Erased<'static, kind::Send>>()
334    );
335};
336const _: () = assert!(mem::size_of::<Id>() == mem::size_of::<u8>());
337const _: () = assert!(mem::size_of::<Route>() == mem::size_of::<u8>());
338const _: () = {
339    assert!(mem::size_of::<Operation<'static, KeyTag<1>>>() == mem::size_of::<Token>());
340    assert!(mem::align_of::<Operation<'static, KeyTag<1>>>() == mem::align_of::<Token>());
341};
342
343/// One framework control decoded without manufacturing a keyed identity.
344#[derive(Clone, Copy, Eq, PartialEq, Debug)]
345#[repr(transparent)]
346pub struct Control(num::NonZero<u64>);
347
348impl From<Control> for num::NonZero<u64> {
349    fn from(control: Control) -> Self {
350        control.0
351    }
352}
353
354impl Control {
355    pub(crate) const fn new(kind: kind::Code, slot: indices::SlotIndex) -> Self {
356        let raw = ((route::FRAMEWORK as u64) << route::SHIFT)
357            | ((kind.raw() as u64) << route::KIND_SHIFT)
358            | slot.raw() as u64;
359        // SAFETY: the nonzero framework route occupies the high byte.
360        Self(unsafe { num::NonZero::<u64>::new_unchecked(raw) })
361    }
362
363    pub const fn slot(self) -> indices::SlotIndex {
364        indices::SlotIndex::from_field(self.0.get())
365    }
366}
367
368impl TryFrom<u64> for Control {
369    type Error = u64;
370
371    fn try_from(raw: u64) -> Result<Self, Self::Error> {
372        if (raw >> route::SHIFT) as u8 != route::FRAMEWORK {
373            return Err(raw);
374        }
375        // SAFETY: a framework-tagged high byte makes the complete word nonzero.
376        Ok(Self(unsafe { num::NonZero::<u64>::new_unchecked(raw) }))
377    }
378}
379
380const _: () = {
381    assert!(mem::size_of::<Token>() == 2 * mem::size_of::<u64>());
382    assert!(mem::size_of::<Option<Token>>() == mem::size_of::<Token>());
383    assert!(mem::size_of::<Control>() == mem::size_of::<u64>());
384    assert!(mem::size_of::<Option<Control>>() == mem::size_of::<Control>());
385};
386
387/// Zero-sized constructor branding table identities with one driver.
388#[derive(Clone, Copy)]
389pub struct Space<'d, Tag: route::Tag> {
390    pub(in crate::driver) driver: route::Brand<'d, Tag>,
391}
392
393impl<'d, Tag: route::Tag> Space<'d, Tag> {
394    pub const fn bind(
395        self,
396        slot: indices::SlotIndex,
397        epoch: route::Epoch,
398    ) -> route::Target<'d, Tag> {
399        route::Target::from_parts(table::Parts::new(slot, epoch), self.driver)
400    }
401
402    pub fn parse<C: kind::Class>(
403        self,
404        target: route::Erased<'d, C>,
405    ) -> Result<route::Operation<'d, Tag, C>, route::Mismatch<'d, Tag, C>>
406    where
407        Tag: route::Select<C>,
408    {
409        if target.route() != Tag::ROUTE {
410            return Err(route::Mismatch::new(target));
411        }
412        Ok(route::Operation::new(target.into_token(), self.driver))
413    }
414}
415
416const _: () = assert!(mem::size_of::<Space<'static, route::KeyTag<1>>>() == 0);
417
418/// One generation-checked target branded by its driver lifetime and route.
419///
420#[derive(Clone, Copy, Debug)]
421#[repr(transparent)]
422pub struct Target<'d, Tag: route::Tag> {
423    parts: table::Parts<Tag>,
424    pub(in crate::driver) driver: route::Brand<'d, Tag>,
425}
426
427impl<'d, Tag: route::Tag> Target<'d, Tag> {
428    pub(in crate::driver::route) const fn from_parts(
429        parts: table::Parts<Tag>,
430        driver: route::Brand<'d, Tag>,
431    ) -> Self {
432        Self { parts, driver }
433    }
434
435    pub const fn parts(self) -> table::Parts<Tag> {
436        self.parts
437    }
438
439    pub const fn slot(self) -> indices::SlotIndex {
440        self.parts.slot()
441    }
442
443    pub const fn epoch(self) -> route::Epoch {
444        self.parts.epoch()
445    }
446
447    pub const fn bind<T>(self, value: T) -> route::Bound<'d, Tag, T> {
448        route::Bound::new(self, value)
449    }
450
451    pub const fn operation<C: kind::Class>(self) -> route::Operation<'d, Tag, C>
452    where
453        Tag: route::Select<C>,
454    {
455        let Self { parts, driver } = self;
456        route::Operation::new(route::Token::encode::<Tag, C>(parts), driver)
457    }
458
459    pub const fn dispatch(self) -> route::Operation<'d, Tag> {
460        let Self { parts, driver } = self;
461        route::Operation::new(route::Token::from_parts(parts), driver)
462    }
463}
464
465impl<'d, Tag: route::Tag, C: kind::Class> From<&route::Operation<'d, Tag, C>> for Target<'d, Tag> {
466    fn from(op: &route::Operation<'d, Tag, C>) -> Self {
467        Self {
468            parts: op.parts(),
469            driver: op.driver,
470        }
471    }
472}
473
474impl<Tag: route::Tag> PartialEq for Target<'_, Tag> {
475    fn eq(&self, other: &Self) -> bool {
476        self.parts == other.parts
477    }
478}
479
480impl<Tag: route::Tag> Eq for Target<'_, Tag> {}
481
482impl<Tag: route::Tag> hash::Hash for Target<'_, Tag> {
483    fn hash<H: hash::Hasher>(&self, state: &mut H) {
484        self.parts.hash(state);
485    }
486}
487
488const _: () = {
489    assert!(mem::size_of::<Target<'static, route::KeyTag<1>>>() == mem::size_of::<route::Token>());
490    assert!(
491        mem::align_of::<Target<'static, route::KeyTag<1>>>() == mem::align_of::<route::Token>()
492    );
493};
494
495/// Affine submission input paired with its exact target.
496///
497#[must_use = "bound submission input must be submitted or dropped"]
498pub struct Bound<'d, Tag: route::Tag, T> {
499    target: route::Target<'d, Tag>,
500    value: T,
501}
502
503impl<'d, Tag: route::Tag, T> Bound<'d, Tag, T> {
504    pub(in crate::driver::route) const fn new(target: route::Target<'d, Tag>, value: T) -> Self {
505        Self { target, value }
506    }
507
508    pub(crate) fn into_parts(self) -> (route::Target<'d, Tag>, T) {
509        (self.target, self.value)
510    }
511}