dope_runtime/executor/raw/
park.rs1use 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#[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 { 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 executor::raw::Drive { turn, driver } = self.drive;
38 map(turn, driver)
39 }
40
41 pub fn into_driver(self) -> retained::Context<'driver, 'root, 'd> {
42 self.drive.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 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 {
89 turn,
90 driver: self.drive.driver.reborrow(),
91 };
92 run(Park { drive })
93 })
94 }
95
96 pub fn share_coord<const N: usize, R>(
97 &mut self,
98 rank: usize,
99 weights: [usize; 2],
100 run: impl FnOnce(Park<'_, '_, 'root, 'd>) -> R,
101 ) -> R {
102 self.drive
103 .turn
104 .coord()
105 .share::<N, _>(rank, weights, || run(self.reborrow()))
106 }
107
108 pub fn now(&mut self) -> clock::Moment<'d> {
110 self.drive.driver.reborrow().driver_ref().clock().now()
111 }
112
113 pub fn next_step(&mut self) -> Option<control::Step<'_, 'd>> {
115 match self.drive.turn.reborrow().coord().take() {
116 quota::Take::Taken => {}
117 quota::Take::Exhausted => return None,
118 }
119 let driver = self.drive.driver.reborrow().into_driver();
120 Some(control::Step::new(driver))
121 }
122}
123
124const fn assert_layout() {
125 type Turn<'a> = Park<'a, 'a, 'a, 'a>;
126
127 assert!(mem::size_of::<Turn<'static>>() == 2 * mem::size_of::<usize>());
128 assert!(mem::align_of::<Turn<'static>>() == mem::align_of::<usize>());
129}
130
131const _: () = assert_layout();