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::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 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 pub fn now(&mut self) -> clock::Moment<'d> {
107 self.drive.driver().driver_ref().clock().now()
108 }
109
110 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();