dope_core/driver/schedule/ready/
mod.rs1use std::{marker, mem, num};
2
3pub(crate) use arena::Arena;
4use arena::{
5 cells::{Drain, Entry, Renewal, Resident, Slots, Table},
6 layout, payload, pool, topology,
7};
8pub use key::retained::Retained;
9use key::{
10 Detached, DispatchKey, FreeIndex, Index, ReservedKey, RootIndex, Staged, TaskIndex, TaskKey,
11 TopologyKey,
12};
13pub(crate) use key::{DynamicIndex, QueueIndex, Stored};
14use kind::Kind;
15use layout::Layout;
16use o3::{
17 base::{marker::ThreadBound, num::Generation},
18 depot::queue::Removal,
19 mem::Lease,
20};
21use payload::{Link, Task};
22use pool::{Chain, Permit, Pool, Reclaimed};
23use record::Record;
24pub use rounds::Rounds;
25use topology::Topology;
26
27use crate::{driver, driver::route, io::fd::identity};
28
29mod arena;
30mod record;
31mod rounds;
32
33pub(super) enum Lane {}
34
35#[derive(Clone, Copy, Debug, PartialEq, Eq)]
37pub struct Stale;
38
39#[derive(Clone, Copy, Eq, PartialEq)]
41#[repr(u8)]
42pub enum Readiness {
43 Idle,
44 Ready,
45}
46
47#[derive(Clone, Copy, Debug, PartialEq, Eq)]
49#[repr(transparent)]
50pub struct Capacity {
51 available: u32,
52}
53
54impl Capacity {
55 const fn new(free: u32) -> Self {
56 Self { available: free }
57 }
58
59 #[must_use]
60 pub const fn available(self) -> usize {
61 self.available as usize
62 }
63}
64
65#[derive(Clone, Copy)]
66pub(in crate::driver) struct Access<'a, 'd> {
67 borrow: marker::PhantomData<fn(&'a ()) -> &'a ()>,
68 driver: driver::Invariant<'d>,
69}
70
71impl<'d> Access<'_, 'd> {
72 pub(in crate::driver) fn new<'a>(driver: &'a driver::Reference<'d>) -> Access<'a, 'd>
73 where
74 'd: 'a,
75 {
76 Access {
77 borrow: marker::PhantomData,
78 driver: driver.brand,
79 }
80 }
81
82 fn bind(self, stored: Stored) -> Key<'d> {
83 Key {
84 stored,
85 arena: self.driver,
86 thread: ThreadBound::NEW,
87 }
88 }
89}
90
91enum TaskParent<'d> {
92 Root,
93 Task(Key<'d>),
94 Stale,
95}
96
97#[doc(hidden)]
98pub mod task;
99pub mod wake;
100
101#[derive(Clone, Copy)]
103#[repr(transparent)]
104pub struct Key<'d> {
105 stored: Stored,
106 arena: driver::Invariant<'d>,
107 thread: ThreadBound,
108}
109
110impl PartialEq for Key<'_> {
111 fn eq(&self, other: &Self) -> bool {
112 self.stored == other.stored
113 }
114}
115
116impl Eq for Key<'_> {}
117
118impl<'d> Key<'d> {
119 fn from_index(index: num::NonZero<u16>, epoch: Generation) -> Self {
120 Self {
121 stored: Stored::from_parts(index, epoch),
122 arena: driver::Invariant(marker::PhantomData),
123 thread: ThreadBound::NEW,
124 }
125 }
126
127 pub(in crate::driver) const fn raw(self) -> Stored {
128 self.stored
129 }
130}
131
132#[derive(Clone, Copy)]
133struct Address<'d> {
134 driver: driver::Reference<'d>,
135 key: Retained<'d>,
136}
137
138impl PartialEq for Address<'_> {
139 fn eq(&self, other: &Self) -> bool {
140 self.driver.is_same(other.driver) && self.key == other.key
141 }
142}
143
144impl Eq for Address<'_> {}
145
146impl<'d> Address<'d> {
147 fn new(driver: driver::Reference<'d>, key: Key<'d>) -> Self {
148 Self {
149 driver,
150 key: Retained(key),
151 }
152 }
153
154 fn wake(self) {
155 self.driver.ready().activate(self.key.0);
156 }
157
158 fn belongs_to(self, driver: driver::Reference<'_>) -> bool {
159 self.driver.is_same(driver)
160 }
161
162 fn key(self) -> Key<'d> {
163 self.key.0
164 }
165
166 fn retarget(self, key: Key<'d>) -> Self {
167 Self::new(self.driver, key)
168 }
169}
170
171#[derive(Clone, Copy)]
173#[repr(transparent)]
174pub struct Target<'d> {
175 address: Address<'d>,
176}
177
178impl PartialEq for Target<'_> {
179 fn eq(&self, other: &Self) -> bool {
180 self.address == other.address
181 }
182}
183
184impl Eq for Target<'_> {}
185
186impl<'d> Target<'d> {
187 pub(crate) fn new(driver: driver::Reference<'d>, key: Key<'d>) -> Self {
188 Self {
189 address: Address::new(driver, key),
190 }
191 }
192
193 pub fn wake(self) {
194 self.address.wake();
195 }
196
197 #[doc(hidden)]
198 pub fn key(&self) -> Retained<'d> {
199 self.address.key
200 }
201
202 pub(in crate::driver) fn receive(self) -> (driver::Reference<'d>, Stored) {
203 (self.address.driver, self.address.key.raw())
204 }
205
206 fn address(self) -> Address<'d> {
207 self.address
208 }
209}
210
211#[derive(Clone, Copy)]
212pub struct Handle<'d> {
213 driver: driver::Reference<'d>,
214 id: identity::Identity<'d>,
215}
216
217impl<'d> Handle<'d> {
218 pub(in crate::driver) const fn new(
219 driver: driver::Reference<'d>,
220 id: identity::Identity<'d>,
221 ) -> Self {
222 Self { driver, id }
223 }
224
225 pub fn set_target<Tag: route::Tag>(self, target: route::Operation<'d, Tag>) {
226 self.driver
227 .descriptors()
228 .set_target(self.id, target.into_token());
229 }
230
231 pub fn activate(self) {
232 if self.driver.descriptors().target(self.id).is_some() {
233 self.driver.ready().arena().activate_fd(self.id);
234 }
235 }
236
237 pub fn key(self) -> Key<'d> {
238 let index = self.id.queue_index();
239 Key::from_index(index.0, self.id.generation())
240 }
241
242 pub fn target(self) -> Target<'d> {
243 Target::new(self.driver, self.key())
244 }
245}
246
247pub struct Slot<'d, Tag: route::Tag> {
250 owner: Lease<DispatchKey<'d>>,
251 target: marker::PhantomData<*mut Tag>,
252}
253
254impl<'d, Tag: route::Tag> Slot<'d, Tag> {
255 fn new(driver: driver::Reference<'d>, key: DispatchKey<'d>) -> Self {
256 Self {
257 owner: Lease::new(key, driver),
258 target: marker::PhantomData,
259 }
260 }
261
262 pub fn activate(&self) {
263 self.owner
264 .item()
265 .ready()
266 .arena()
267 .stored()
268 .activate(self.dispatch_key());
269 }
270
271 #[must_use]
273 pub fn take(&self) -> Readiness {
274 match self
275 .owner
276 .item()
277 .ready()
278 .arena()
279 .stored()
280 .take(self.dispatch_key())
281 {
282 Removal::Removed => Readiness::Ready,
283 Removal::Absent => Readiness::Idle,
284 }
285 }
286
287 pub fn target(&self) -> Target<'d> {
289 Target::new(*self.owner.item(), self.dispatch_key().key())
290 }
291
292 fn dispatch_key(&self) -> &DispatchKey<'d> {
293 self.owner.sink()
294 }
295}
296
297const _: () = {
298 assert!(mem::size_of::<Readiness>() == mem::size_of::<u8>());
299 assert!(mem::size_of::<usize>() >= mem::size_of::<u32>());
300 assert!(mem::size_of::<Access<'static, 'static>>() == 0);
301};
302const _: () = {
303 assert!(mem::size_of::<Key<'static>>() == mem::size_of::<u64>());
304 assert!(mem::size_of::<Option<Key<'static>>>() == mem::size_of::<Key<'static>>());
305 assert!(mem::size_of::<Option<Retained<'static>>>() == mem::size_of::<Retained<'static>>());
306 assert!(mem::size_of::<DispatchKey<'static>>() == mem::size_of::<Key<'static>>());
307 assert!(mem::align_of::<DispatchKey<'static>>() == mem::align_of::<Key<'static>>());
308 assert!(mem::size_of::<Slot<'static, route::KeyTag<0>>>() == 2 * mem::size_of::<usize>());
309};
310const _: () = assert!(mem::size_of::<Target<'static>>() == 2 * mem::size_of::<usize>());
311const _: () = {
312 assert!(mem::size_of::<Handle<'static>>() == 2 * mem::size_of::<usize>());
313};
314
315mod key;
316mod kind;
317mod state;
318
319#[derive(Clone, Copy)]
320#[repr(transparent)]
321pub struct Context<'d>(driver::Reference<'d>);
322
323impl<'d> Context<'d> {
324 pub(in crate::driver) const fn new(driver: driver::Reference<'d>) -> Self {
325 Self(driver)
326 }
327
328 pub(crate) fn arena(self) -> &'d Arena {
329 self.0.shared.context().schedule.owner.context()
330 }
331
332 pub(crate) fn handle(self, id: identity::Identity<'d>) -> Handle<'d> {
333 Handle::new(self.0, id)
334 }
335
336 pub fn make_slot<Tag: route::Tag>(
337 self,
338 target: route::Operation<'d, Tag>,
339 ) -> Result<Slot<'d, Tag>, Capacity> {
340 self.arena().make_slot(self.0, target)
341 }
342
343 pub fn activate(self, key: Key<'d>) {
346 self.arena().activate(Access::new(&self.0), key);
347 }
348
349 pub fn try_activate(self, key: Retained<'d>) -> Result<(), Stale> {
351 self.arena().stored().try_retained(key)
352 }
353
354 pub fn has_ready(self) -> bool {
355 self.arena().has_ready()
356 }
357}
358
359const _: () = assert!(
360 std::mem::size_of::<Context<'static>>() == std::mem::size_of::<driver::Reference<'static>>()
361);