Skip to main content

dope_runtime/executor/raw/
park.rs

1use std::{mem, pin};
2
3use dope_core::driver::{
4    retained,
5    schedule::{self, clock},
6};
7use o3::mem::quota;
8
9use crate::{control, executor};
10
11/// Pre-park authority for one exact retained root and scheduler turn.
12#[must_use]
13pub struct Park<'driver, 'turn, 'root, 'd: 'root> {
14    drive: executor::raw::Drive<'driver, 'turn, 'root, 'd>,
15}
16
17impl<'driver, 'turn, 'root, 'd: 'root> Park<'driver, 'turn, 'root, 'd> {
18    pub(crate) const fn new(
19        turn: schedule::Turn<'turn, 'd>,
20        driver: retained::Context<'driver, 'root, 'd>,
21    ) -> Self {
22        Self {
23            drive: executor::raw::Drive::new(turn, driver),
24        }
25    }
26
27    pub fn reborrow(&mut self) -> Park<'_, '_, 'root, 'd> {
28        Park {
29            drive: self.drive.reborrow(),
30        }
31    }
32
33    pub fn map<R>(
34        self,
35        map: impl FnOnce(schedule::Turn<'turn, 'd>, retained::Context<'driver, 'root, 'd>) -> R,
36    ) -> R {
37        let (turn, driver) = self.drive.into_parts();
38        map(turn, driver)
39    }
40
41    pub fn into_driver(self) -> retained::Context<'driver, 'root, 'd> {
42        self.drive.into_driver()
43    }
44
45    pub(crate) fn run<R>(self, app: pin::Pin<&mut R>, plan: &mut Option<R::ParkPlan>)
46    where
47        R: executor::raw::App<'d>,
48    {
49        if let Some(plan) = plan {
50            // SAFETY: publication prepared this plan for the same installed pinned root.
51            // Failed admission runs forced finish without entering a park operation.
52            unsafe { R::park(app, plan, self) }
53        }
54    }
55
56    pub fn app_cursor<const N: usize>(
57        &self,
58        cursor: &mut executor::raw::Cursor<N>,
59    ) -> executor::raw::Cursor<N> {
60        cursor.start(self.drive.turn.app().remaining())
61    }
62
63    pub fn maint_cursor<const N: usize>(
64        &self,
65        cursor: &mut executor::raw::Cursor<N>,
66    ) -> executor::raw::Cursor<N> {
67        cursor.start(self.drive.turn.maint().remaining())
68    }
69
70    pub fn coord_cursor<const N: usize>(
71        &self,
72        cursor: &mut executor::raw::Cursor<N>,
73    ) -> executor::raw::Cursor<N> {
74        cursor.start(self.drive.turn.coord().remaining())
75    }
76
77    pub fn coord_left(&self) -> usize {
78        self.drive.turn.coord().remaining()
79    }
80
81    pub fn share<const N: usize, R>(
82        &mut self,
83        ranks: [usize; 3],
84        weights: [usize; 2],
85        run: impl FnOnce(Park<'_, '_, 'root, 'd>) -> R,
86    ) -> R {
87        self.drive.turn.share::<N, _>(ranks, weights, |turn| {
88            let drive = executor::raw::Drive::new(turn, self.drive.driver());
89            run(Park { drive })
90        })
91    }
92
93    pub fn share_coord<const N: usize, R>(
94        &mut self,
95        rank: usize,
96        weights: [usize; 2],
97        run: impl FnOnce(Park<'_, '_, 'root, 'd>) -> R,
98    ) -> R {
99        self.drive
100            .turn
101            .coord()
102            .share::<N, _>(rank, weights, || run(self.reborrow()))
103    }
104
105    /// Monotonic time captured once at the beginning of this driver turn.
106    pub fn now(&mut self) -> clock::Moment<'d> {
107        self.drive.driver().driver_ref().clock().now()
108    }
109
110    /// Admits one step whose clock and region authorities share this borrow.
111    pub fn next_step(&mut self) -> Option<control::Step<'_, 'd>> {
112        match self.drive.turn().coord().take() {
113            quota::Take::Taken => {}
114            quota::Take::Exhausted => return None,
115        }
116        let driver = self.drive.driver().into_driver();
117        Some(control::Step::new(driver))
118    }
119}
120
121const fn assert_layout() {
122    type Turn<'a> = Park<'a, 'a, 'a, 'a>;
123
124    assert!(mem::size_of::<Turn<'static>>() == 2 * mem::size_of::<usize>());
125    assert!(mem::align_of::<Turn<'static>>() == mem::align_of::<usize>());
126}
127
128const _: () = assert_layout();