dope_runtime/executor/raw/
park.rs1use std::{mem, pin};
2
3use dope_core::driver::{
4 self,
5 schedule::{self, clock},
6};
7use o3::mem::quota;
8
9use crate::{control, executor};
10
11#[must_use]
13pub struct Park<'driver, 'turn, 'd> {
14 drive: executor::raw::Drive<'driver, 'turn, 'd>,
15}
16
17impl<'driver, 'turn, 'd> Park<'driver, 'turn, 'd> {
18 pub(crate) const fn new(
19 turn: schedule::Turn<'turn, 'd>,
20 driver: driver::Context<'driver, 'd>,
21 ) -> Self {
22 Self {
23 drive: executor::raw::Drive { turn, driver },
24 }
25 }
26
27 pub fn reborrow(&mut self) -> Park<'_, '_, 'd> {
28 Park {
29 drive: self.drive.reborrow(),
30 }
31 }
32
33 pub fn into_parts(self) -> (schedule::Turn<'turn, 'd>, driver::Context<'driver, 'd>) {
34 let executor::raw::Drive { turn, driver } = self.drive;
35 (turn, driver)
36 }
37
38 pub fn into_driver(self) -> driver::Context<'driver, 'd> {
39 self.drive.driver
40 }
41
42 pub(crate) fn run<R>(self, app: pin::Pin<&mut R>, plan: &mut Option<R::ParkPlan>)
43 where
44 R: executor::raw::App<'d>,
45 {
46 if let Some(plan) = plan {
47 unsafe { R::park(app, plan, self) }
50 }
51 }
52
53 pub fn app_cursor<const N: usize>(
54 &self,
55 cursor: &mut executor::raw::Cursor<N>,
56 ) -> executor::raw::Cursor<N> {
57 cursor.start(self.drive.turn.app().remaining())
58 }
59
60 pub fn maint_cursor<const N: usize>(
61 &self,
62 cursor: &mut executor::raw::Cursor<N>,
63 ) -> executor::raw::Cursor<N> {
64 cursor.start(self.drive.turn.maint().remaining())
65 }
66
67 pub fn coord_cursor<const N: usize>(
68 &self,
69 cursor: &mut executor::raw::Cursor<N>,
70 ) -> executor::raw::Cursor<N> {
71 cursor.start(self.drive.turn.coord().remaining())
72 }
73
74 pub fn coord_left(&self) -> usize {
75 self.drive.turn.coord().remaining()
76 }
77
78 pub fn share<const N: usize, R>(
79 &mut self,
80 ranks: [usize; 3],
81 weights: [usize; 2],
82 run: impl FnOnce(Park<'_, '_, 'd>) -> R,
83 ) -> R {
84 self.drive.turn.share::<N, _>(ranks, weights, |turn| {
85 let drive = executor::raw::Drive {
86 turn,
87 driver: self.drive.driver.reborrow(),
88 };
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<'_, '_, '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.reborrow().driver_ref().clock().now()
108 }
109
110 pub fn next_step(&mut self) -> Option<control::Step<'_, 'd>> {
112 match self.drive.turn.reborrow().coord().take() {
113 quota::Take::Taken => {}
114 quota::Take::Exhausted => return None,
115 }
116 let driver = self.drive.driver.reborrow();
117 Some(control::Step::new(driver))
118 }
119}
120
121const fn assert_layout() {
122 type Turn<'a> = Park<'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();