Skip to main content

dope_core/driver/route/
token.rs

1use core::{hash, marker, num};
2
3use o3::base::marker::ThreadBound;
4
5use crate::driver::{
6    route,
7    route::{Epoch, indices, indices::SlotIndex, kind, table},
8};
9
10#[derive(Clone, Copy, PartialEq, Eq, Debug)]
11#[repr(C)]
12pub struct Token {
13    pub(super) epoch: num::NonZero<u64>,
14    pub(super) thread: ThreadBound,
15    pub(super) meta: u64,
16}
17
18impl hash::Hash for Token {
19    fn hash<H: hash::Hasher>(&self, state: &mut H) {
20        hash::Hash::hash(&self.epoch.get(), state);
21        hash::Hash::hash(&self.meta, state);
22    }
23}
24
25impl Token {
26    pub(in crate::driver) const fn from_flight(
27        epoch: route::Epoch,
28        slot: indices::SlotIndex,
29        kind: kind::Native,
30        route: route::Route,
31    ) -> Self {
32        Self::pack(route, kind as u8, slot, epoch)
33    }
34
35    const fn pack(
36        route: route::Route,
37        kind: u8,
38        slot: indices::SlotIndex,
39        epoch: route::Epoch,
40    ) -> Self {
41        let (epoch, thread) = epoch.into_parts();
42        Self {
43            epoch,
44            thread,
45            meta: ((route.raw() as u64) << route::SHIFT)
46                | ((kind as u64) << route::KIND_SHIFT)
47                | slot.raw() as u64,
48        }
49    }
50
51    pub const fn route(self) -> route::Route {
52        route::Route::from_bits((self.meta >> route::SHIFT) as u8)
53    }
54
55    pub const fn kind(self) -> Result<kind::Kind, kind::Unknown> {
56        let raw = self.kind_raw();
57        match raw {
58            0 => Ok(kind::Kind::Unspecified),
59            1 => Ok(kind::Kind::Accept),
60            2 => Ok(kind::Kind::Recv),
61            3 => Ok(kind::Kind::Send),
62            5 => Ok(kind::Kind::Socket),
63            6 => Ok(kind::Kind::Connect),
64            7 => Ok(kind::Kind::Shutdown),
65            11 => Ok(kind::Kind::Open),
66            19 => Ok(kind::Kind::OneShot),
67            21 => Ok(kind::Kind::TaskQueue),
68            25 => Ok(kind::Kind::Tuning),
69            28 => Ok(kind::Kind::Write),
70            29 => Ok(kind::Kind::Sync),
71            30 => Ok(kind::Kind::Read),
72            unknown => Err(kind::Unknown::new(unknown)),
73        }
74    }
75
76    pub(crate) const fn kind_raw(self) -> u8 {
77        (self.meta >> route::KIND_SHIFT) as u8
78    }
79
80    pub const fn slot(self) -> indices::SlotIndex {
81        SlotIndex::from_field(self.meta)
82    }
83
84    pub const fn epoch(self) -> route::Epoch {
85        Epoch::new(self.epoch, self.thread)
86    }
87
88    pub(super) const fn encode<Tag, C>(parts: table::Parts<Tag>) -> Self
89    where
90        Tag: route::Select<C>,
91        C: kind::Class,
92    {
93        Self::pack(Tag::ROUTE, C::CODE.raw(), parts.slot(), parts.epoch())
94    }
95
96    #[doc(hidden)]
97    pub const fn from_parts<Tag: route::Tag>(parts: table::Parts<Tag>) -> Self {
98        Self::pack(
99            Tag::ROUTE,
100            <Tag::Class as kind::Class>::CODE.raw(),
101            parts.slot(),
102            parts.epoch(),
103        )
104    }
105}
106
107#[derive(Clone, Copy, Debug)]
108pub(crate) struct Brand<'d, Tag> {
109    pub(super) driver: crate::driver::Invariant<'d>,
110    tag: marker::PhantomData<*mut Tag>,
111}
112
113impl<'d, Tag> Brand<'d, Tag> {
114    pub(crate) const fn new(driver: crate::driver::Invariant<'d>) -> Self {
115        Self {
116            driver,
117            tag: marker::PhantomData,
118        }
119    }
120}
121
122#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
123#[repr(transparent)]
124pub(crate) struct OutboundKey(u8);
125
126impl OutboundKey {
127    pub(crate) const fn raw(self) -> u32 {
128        self.0 as u32
129    }
130
131    pub(crate) const fn from_raw(raw: u32) -> Option<Self> {
132        if raw < route::FRAMEWORK as u32 {
133            Some(Self(raw as u8))
134        } else {
135            None
136        }
137    }
138
139    /// Type-branded outbound key for callers that carry an application route tag.
140    pub(crate) const fn for_tag<Tag: route::Tag>() -> Self {
141        const { assert!(Tag::ROUTE.raw() != route::FRAMEWORK) };
142        Self(Tag::ROUTE.raw())
143    }
144}