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{
139}
140
141/// One route identity materialized as a specific operation class.
142///
143/// The class a route is used in is part of the tag's type, so naming it is a
144/// type-level projection this trait carries for an unspecified class.
145pub trait Materialize<C: kind::Class>: Tag<Class = kind::Any> {
146    type With: App<Class = C> + Select<C>;
147}
148
149impl<const ROUTE: u8> Identity for KeyTag<ROUTE, kind::Any> {}
150
151impl<const ROUTE: u8, C: kind::Class> Materialize<C> for KeyTag<ROUTE, kind::Any>
152where
153    KeyTag<ROUTE, C>: App<Class = C> + Select<C>,
154{
155    type With = KeyTag<ROUTE, C>;
156}
157
158/// A tag carries only its route and class as types, so every value of one tag
159/// type is the same identity and hashes by that route.
160impl<const ROUTE: u8, C: kind::Class> PartialEq for KeyTag<ROUTE, C> {
161    fn eq(&self, _: &Self) -> bool {
162        true
163    }
164}
165
166impl<const ROUTE: u8, C: kind::Class> Eq for KeyTag<ROUTE, C> {}
167
168impl<const ROUTE: u8, C: kind::Class> hash::Hash for KeyTag<ROUTE, C> {
169    fn hash<H: hash::Hasher>(&self, state: &mut H) {
170        state.write_u8(ROUTE);
171    }
172}
173
174impl<const ROUTE: u8, C: kind::Class> Tag for KeyTag<ROUTE, C> {
175    const ROUTE: Route = Id::fixed::<ROUTE>().into_route();
176    type Class = C;
177}
178
179impl<const ROUTE: u8, C: kind::Class> App for KeyTag<ROUTE, C> {
180    const ID: Id = Id::fixed::<ROUTE>();
181}
182
183impl<const ROUTE: u8, C: kind::Class> kind::Sealed for KeyTag<ROUTE, C> {}
184
185impl<C: kind::Class> Tag for FrameworkTag<C> {
186    const ROUTE: Route = Route::FRAMEWORK;
187    type Class = C;
188}
189
190impl<T: Tag<Class = kind::Any>, C: kind::Class> Select<C> for T {}
191/// One operation identity branded by its driver lifetime and route.
192#[derive(Clone, Copy)]
193#[repr(transparent)]
194pub struct Operation<'d, T: Tag, C: kind::Class = <T as Tag>::Class> {
195    token: Token,
196    driver: Brand<'d, T>,
197    class: marker::PhantomData<C>,
198}
199
200impl<'d, T: Tag, C: kind::Class> Operation<'d, T, C> {
201    pub(super) const fn new(token: Token, driver: Brand<'d, T>) -> Self {
202        Self {
203            token,
204            driver,
205            class: marker::PhantomData,
206        }
207    }
208
209    pub fn matches(self, target: Erased<'d, C>) -> bool {
210        self.token == target.token
211    }
212
213    pub const fn parts(self) -> table::Parts<T> {
214        table::Parts::new(self.token.slot(), self.token.epoch())
215    }
216
217    pub const fn erase_route(self) -> Erased<'d, C> {
218        Erased::new(self.token, self.driver.driver).bind(kind::Witness(self.class))
219    }
220
221    pub(crate) const fn into_token(self) -> Token {
222        self.token
223    }
224}
225
226impl<T: Tag, C: kind::Class> PartialEq for Operation<'_, T, C> {
227    fn eq(&self, other: &Self) -> bool {
228        self.token == other.token
229    }
230}
231
232impl<T: Tag, C: kind::Class> Eq for Operation<'_, T, C> {}
233
234impl<T: Tag, C: kind::Class> hash::Hash for Operation<'_, T, C> {
235    fn hash<H: hash::Hasher>(&self, state: &mut H) {
236        self.token.hash(state);
237    }
238}
239
240/// Logical operation target with its native flight identity when submitted.
241#[derive(Clone, Copy)]
242#[repr(C)]
243pub struct Erased<'d, C: kind::Class> {
244    pub(in crate::driver) token: Token,
245    // Completion delivery preserves the already-admitted native identity even
246    // after its arena slot is released. Logical routing remains independent.
247    pub(in crate::driver) flight: Option<super::retained::flight::raw::Echo>,
248    pub(in crate::driver) driver: super::Invariant<'d>,
249    pub(in crate::driver) class: marker::PhantomData<C>,
250}
251
252impl<'d> Erased<'d, kind::Any> {
253    pub(in crate::driver) const fn new(token: Token, driver: super::Invariant<'d>) -> Self {
254        Self {
255            token,
256            flight: None,
257            driver,
258            class: marker::PhantomData,
259        }
260    }
261
262    pub(crate) const fn bind<C: kind::Class>(self, proof: kind::Witness<C>) -> Erased<'d, C> {
263        let kind::Witness(class) = proof;
264        Erased {
265            token: self.token,
266            flight: self.flight,
267            driver: self.driver,
268            class,
269        }
270    }
271}
272
273impl<'d, C: kind::Class> Erased<'d, C> {
274    pub fn matches(self, target: Self) -> bool {
275        self.token == target.token
276    }
277
278    pub(crate) fn matches_flight(self, target: Self) -> bool {
279        // The shared driver brand fixes the arena; an echo is never reused and
280        // identifies one immutable target.
281        self.flight.is_some() && self.flight == target.flight
282    }
283
284    pub const fn route(self) -> Route {
285        self.token.route()
286    }
287
288    pub const fn slot(self) -> SlotIndex {
289        self.token.slot()
290    }
291
292    pub const fn epoch(self) -> Epoch {
293        self.token.epoch()
294    }
295
296    pub(crate) const fn into_token(self) -> Token {
297        self.token
298    }
299}
300
301/// A class-typed operation that belongs to another route.
302pub struct Mismatch<'d, T: Tag, C: kind::Class> {
303    target: Erased<'d, C>,
304    tag: marker::PhantomData<T>,
305}
306
307impl<'d, T: Tag, C: kind::Class> Mismatch<'d, T, C> {
308    const fn new(target: Erased<'d, C>) -> Self {
309        Self {
310            target,
311            tag: marker::PhantomData,
312        }
313    }
314
315    pub fn into_target(self) -> Erased<'d, C> {
316        self.target
317    }
318}
319
320pub mod kind;
321
322pub const SHUTDOWN: Control = Control::new(<kind::Shutdown as kind::Class>::CODE, SlotIndex::ZERO);
323
324const _: () = {
325    assert!(
326        mem::size_of::<Erased<'static, kind::Send>>()
327            == mem::size_of::<Token>() + mem::size_of::<usize>()
328    );
329    assert!(mem::align_of::<Erased<'static, kind::Send>>() == mem::align_of::<Token>());
330    assert!(
331        mem::size_of::<Mismatch<'static, KeyTag<1>, kind::Send>>()
332            == mem::size_of::<Erased<'static, kind::Send>>()
333    );
334};
335const _: () = assert!(mem::size_of::<Id>() == mem::size_of::<u8>());
336const _: () = assert!(mem::size_of::<Route>() == mem::size_of::<u8>());
337const _: () = {
338    assert!(mem::size_of::<Operation<'static, KeyTag<1>>>() == mem::size_of::<Token>());
339    assert!(mem::align_of::<Operation<'static, KeyTag<1>>>() == mem::align_of::<Token>());
340};
341
342/// One framework control decoded without manufacturing a keyed identity.
343#[derive(Clone, Copy, Eq, PartialEq, Debug)]
344#[repr(transparent)]
345pub struct Control(num::NonZero<u64>);
346
347impl From<Control> for num::NonZero<u64> {
348    fn from(control: Control) -> Self {
349        control.0
350    }
351}
352
353impl Control {
354    pub(crate) const fn new(kind: kind::Code, slot: indices::SlotIndex) -> Self {
355        let raw = ((route::FRAMEWORK as u64) << route::SHIFT)
356            | ((kind.raw() as u64) << route::KIND_SHIFT)
357            | slot.raw() as u64;
358        // SAFETY: the nonzero framework route occupies the high byte.
359        Self(unsafe { num::NonZero::<u64>::new_unchecked(raw) })
360    }
361
362    pub const fn slot(self) -> indices::SlotIndex {
363        indices::SlotIndex::from_field(self.0.get())
364    }
365}
366
367impl TryFrom<u64> for Control {
368    type Error = u64;
369
370    fn try_from(raw: u64) -> Result<Self, Self::Error> {
371        if (raw >> route::SHIFT) as u8 != route::FRAMEWORK {
372            return Err(raw);
373        }
374        // SAFETY: a framework-tagged high byte makes the complete word nonzero.
375        Ok(Self(unsafe { num::NonZero::<u64>::new_unchecked(raw) }))
376    }
377}
378
379const _: () = {
380    assert!(mem::size_of::<Token>() == 2 * mem::size_of::<u64>());
381    assert!(mem::size_of::<Option<Token>>() == mem::size_of::<Token>());
382    assert!(mem::size_of::<Control>() == mem::size_of::<u64>());
383    assert!(mem::size_of::<Option<Control>>() == mem::size_of::<Control>());
384};
385
386/// Zero-sized constructor branding table identities with one driver.
387#[derive(Clone, Copy)]
388pub struct Space<'d, Tag: route::Tag> {
389    pub(in crate::driver) driver: route::Brand<'d, Tag>,
390}
391
392impl<'d, Tag: route::Tag> Space<'d, Tag> {
393    pub const fn bind(
394        self,
395        slot: indices::SlotIndex,
396        epoch: route::Epoch,
397    ) -> route::Target<'d, Tag> {
398        route::Target::from_parts(table::Parts::new(slot, epoch), self.driver)
399    }
400
401    pub fn parse<C: kind::Class>(
402        self,
403        target: route::Erased<'d, C>,
404    ) -> Result<route::Operation<'d, Tag, C>, route::Mismatch<'d, Tag, C>>
405    where
406        Tag: route::Select<C>,
407    {
408        if target.route() != Tag::ROUTE {
409            return Err(route::Mismatch::new(target));
410        }
411        Ok(route::Operation::new(target.into_token(), self.driver))
412    }
413}
414
415const _: () = assert!(mem::size_of::<Space<'static, route::KeyTag<1>>>() == 0);
416
417/// One generation-checked target branded by its driver lifetime and route.
418///
419#[derive(Clone, Copy, Debug)]
420#[repr(transparent)]
421pub struct Target<'d, Tag: route::Tag> {
422    parts: table::Parts<Tag>,
423    pub(in crate::driver) driver: route::Brand<'d, Tag>,
424}
425
426impl<'d, Tag: route::Tag> Target<'d, Tag> {
427    pub(in crate::driver::route) const fn from_parts(
428        parts: table::Parts<Tag>,
429        driver: route::Brand<'d, Tag>,
430    ) -> Self {
431        Self { parts, driver }
432    }
433
434    pub const fn parts(self) -> table::Parts<Tag> {
435        self.parts
436    }
437
438    pub const fn slot(self) -> indices::SlotIndex {
439        self.parts.slot()
440    }
441
442    pub const fn epoch(self) -> route::Epoch {
443        self.parts.epoch()
444    }
445
446    pub const fn bind<T>(self, value: T) -> route::Bound<'d, Tag, T> {
447        route::Bound::new(self, value)
448    }
449
450    pub const fn operation<C: kind::Class>(self) -> route::Operation<'d, Tag, C>
451    where
452        Tag: route::Select<C>,
453    {
454        let Self { parts, driver } = self;
455        route::Operation::new(route::Token::encode::<Tag, C>(parts), driver)
456    }
457
458    pub const fn dispatch(self) -> route::Operation<'d, Tag> {
459        let Self { parts, driver } = self;
460        route::Operation::new(route::Token::from_parts(parts), driver)
461    }
462}
463
464impl<'d, Tag: route::Tag, C: kind::Class> From<&route::Operation<'d, Tag, C>> for Target<'d, Tag> {
465    fn from(op: &route::Operation<'d, Tag, C>) -> Self {
466        Self {
467            parts: op.parts(),
468            driver: op.driver,
469        }
470    }
471}
472
473impl<Tag: route::Tag> PartialEq for Target<'_, Tag> {
474    fn eq(&self, other: &Self) -> bool {
475        self.parts == other.parts
476    }
477}
478
479impl<Tag: route::Tag> Eq for Target<'_, Tag> {}
480
481impl<Tag: route::Tag> hash::Hash for Target<'_, Tag> {
482    fn hash<H: hash::Hasher>(&self, state: &mut H) {
483        self.parts.hash(state);
484    }
485}
486
487const _: () = {
488    assert!(mem::size_of::<Target<'static, route::KeyTag<1>>>() == mem::size_of::<route::Token>());
489    assert!(
490        mem::align_of::<Target<'static, route::KeyTag<1>>>() == mem::align_of::<route::Token>()
491    );
492};
493
494/// Affine submission input paired with its exact target.
495///
496#[must_use = "bound submission input must be submitted or dropped"]
497pub struct Bound<'d, Tag: route::Tag, T> {
498    target: route::Target<'d, Tag>,
499    value: T,
500}
501
502impl<'d, Tag: route::Tag, T> Bound<'d, Tag, T> {
503    pub(in crate::driver::route) const fn new(target: route::Target<'d, Tag>, value: T) -> Self {
504        Self { target, value }
505    }
506
507    pub(crate) fn into_parts(self) -> (route::Target<'d, Tag>, T) {
508        (self.target, self.value)
509    }
510}