dope_core/driver/schedule/
sequence.rs1use std::{cell, hash, mem, num};
2
3use o3::base::marker::ThreadBound;
4
5use crate::driver;
6
7const LOCAL: u64 = u32::MAX as u64;
8const BLOCK: u64 = 1_u64 << u32::BITS;
9
10pub(in crate::driver) struct Owner(cell::Cell<Option<num::NonZero<u64>>>);
11
12impl Owner {
13 pub(in crate::driver) const fn new() -> Self {
14 Self(cell::Cell::new(Some(num::NonZero::<u64>::MIN)))
15 }
16
17 fn claim(&self) -> Option<num::NonZero<u64>> {
18 let first = self.0.get()?;
19 let skip = 1_u32.wrapping_sub(first.get() as u32);
20 let first = first.checked_add(u64::from(skip))?;
21 self.0.set(first.checked_add(BLOCK));
22 Some(first)
23 }
24
25 pub(in crate::driver) fn next(&self) -> Option<num::NonZero<u64>> {
26 let next = self.0.get()?;
27 self.0.set(next.checked_add(1));
28 Some(next)
29 }
30}
31
32#[derive(Clone, Copy, Debug, Eq, PartialEq)]
33pub struct Exhausted;
34
35#[derive(Clone, Copy, Debug, Eq, PartialEq)]
40#[repr(transparent)]
41pub struct Id<'d> {
42 raw: num::NonZero<u64>,
43 driver: driver::Invariant<'d>,
44 thread: ThreadBound,
45}
46
47impl<'d> Id<'d> {
48 pub(in crate::driver) fn new(driver: driver::Reference<'d>, raw: num::NonZero<u64>) -> Self {
49 Self {
50 raw,
51 driver: driver.brand,
52 thread: ThreadBound::NEW,
53 }
54 }
55}
56
57impl hash::Hash for Id<'_> {
58 fn hash<H: hash::Hasher>(&self, state: &mut H) {
59 self.raw.hash(state);
60 }
61}
62
63pub struct Block<'d> {
64 driver: driver::Reference<'d>,
65 next: cell::Cell<Option<num::NonZero<u64>>>,
66}
67
68impl<'d> Block<'d> {
69 pub(in crate::driver) fn new(driver: driver::Reference<'d>) -> Self {
70 let next = driver.shared.context().sequence.claim();
71 Self {
72 driver,
73 next: cell::Cell::new(next),
74 }
75 }
76
77 pub fn try_next(&self) -> Result<Id<'d>, Exhausted> {
78 let raw = match self.next.get() {
79 Some(raw) => raw,
80 None => self
81 .driver
82 .shared
83 .context()
84 .sequence
85 .claim()
86 .ok_or(Exhausted)?,
87 };
88 let next = raw.checked_add(1).filter(|next| next.get() & LOCAL != 0);
89 self.next.set(next);
90 Ok(Id::new(self.driver, raw))
91 }
92}
93
94const _: () = {
95 assert!(mem::size_of::<Block<'static>>() == 2 * mem::size_of::<usize>());
96 assert!(mem::size_of::<Id<'static>>() == mem::size_of::<num::NonZero<u64>>());
97 assert!(mem::size_of::<Result<Id<'static>, Exhausted>>() == mem::size_of::<usize>());
98};