1use std::{mem, ops, pin, ptr};
2
3use dope_core::{
4 driver::{retained, schedule, settings},
5 io,
6};
7use o3::base::cell::region;
8
9use super::forward;
10use crate::{executor, topology::lending};
11
12#[pin_project::pin_project]
14#[repr(transparent)]
15pub struct Bound<'app, 'd, H, T> {
16 #[pin]
17 pub(super) inner: lending::raw::Pair<'app, 'd, H, T>,
18}
19
20impl<'app, 'd, H, T> Bound<'app, 'd, H, T> {
21 pub(crate) const fn new(head: pin::Pin<&'app mut H>, tail: T) -> Self {
22 const {
23 assert!(mem::size_of::<Self>() == mem::size_of::<(pin::Pin<&'app mut H>, T)>());
24 assert!(mem::align_of::<Self>() == mem::align_of::<(pin::Pin<&'app mut H>, T)>());
25 assert!(!mem::needs_drop::<Self>());
26 }
27 Self {
28 inner: lending::raw::Pair::new(head, tail),
29 }
30 }
31
32 pub fn tail(self: pin::Pin<&Self>) -> pin::Pin<&T> {
33 self.project_ref().inner.tail()
34 }
35}
36
37unsafe impl<'app, 'd, H, T> lending::raw::Project for Bound<'app, 'd, H, T> {
39 type App = lending::raw::Pair<'app, 'd, H, T>;
40
41 fn shared(self: pin::Pin<&Self>) -> pin::Pin<&Self::App> {
42 self.project_ref().inner
43 }
44
45 fn exclusive(self: pin::Pin<&mut Self>) -> pin::Pin<&mut Self::App> {
46 self.project().inner
47 }
48}
49
50impl<'app, 'd, H, T> executor::raw::Layout<'d> for Bound<'app, 'd, H, T>
51where
52 H: executor::raw::Layout<'d>,
53 T: executor::raw::Layout<'d>,
54{
55 type ParkPlan = <lending::raw::Pair<'app, 'd, H, T> as executor::raw::Layout<'d>>::ParkPlan;
56}
57
58unsafe impl<'app, 'd, H, T> executor::raw::App<'d> for Bound<'app, 'd, H, T>
62where
63 H: executor::raw::App<'d>,
64 T: executor::raw::App<'d>,
65{
66 const ROUTES: settings::Routes =
67 <lending::raw::Pair<'app, 'd, H, T> as executor::raw::App<'d>>::ROUTES;
68 const WAKE_ROUTES: settings::Routes =
69 <lending::raw::Pair<'app, 'd, H, T> as executor::raw::App<'d>>::WAKE_ROUTES;
70 const COORDS: usize = <lending::raw::Pair<'app, 'd, H, T> as executor::raw::App<'d>>::COORDS;
71
72 fn select_park() -> Option<Self::ParkPlan> {
73 <lending::raw::Pair<'app, 'd, H, T> as executor::raw::App<'d>>::select_park()
74 }
75
76 fn prepare_park(
77 app: pin::Pin<&Self>,
78 plan: &mut Self::ParkPlan,
79 ) -> Option<executor::raw::Count> {
80 <lending::raw::Pair<'app, 'd, H, T> as executor::raw::App<'d>>::prepare_park(
81 lending::raw::Project::shared(app),
82 plan,
83 )
84 }
85
86 unsafe fn park<'call, 'driver, 'turn, 'root>(
87 app: pin::Pin<&'call mut Self>,
88 plan: &mut Self::ParkPlan,
89 park: executor::raw::Park<'driver, 'turn, 'root, 'd>,
90 ) where
91 'd: 'driver + 'turn + 'root,
92 {
93 unsafe { forward::park(app, plan, park) }
95 }
96
97 unsafe fn activate<'call, 'driver, 'turn, 'root>(
98 app: pin::Pin<&'call mut Self>,
99 activate: executor::raw::Activate<'driver, 'turn, 'root, 'd>,
100 ) -> bool
101 where
102 'd: 'driver + 'turn + 'root,
103 {
104 unsafe { forward::activate(app, activate) }
106 }
107
108 fn admit(
109 app: pin::Pin<&Self>,
110 needs: &mut settings::claim::Needs,
111 ) -> Result<(), settings::errors::Claim> {
112 <lending::raw::Pair<'_, 'd, H, T> as executor::raw::App<'d>>::admit(
113 lending::raw::Project::shared(app),
114 needs,
115 )
116 }
117
118 fn released(released: executor::raw::Released<'_, Self>) -> executor::raw::Released<'_, Self> {
119 unsafe { released.visit(|app| app.project().inner.project().tail) }
122 }
123
124 fn install<'call, 'owner>(
125 call: executor::raw::Install<'call, 'owner, 'd, Self>,
126 ) -> executor::raw::Install<'call, 'owner, 'd, Self> {
127 forward::install(call)
128 }
129
130 fn dispatch<'call, 'driver, 'turn, 'root>(
131 call: executor::raw::Dispatch<'call, 'driver, 'turn, 'root, 'd, Self>,
132 ) -> ops::ControlFlow<io::Event<'d>>
133 where
134 'd: 'root,
135 Self: 'root,
136 {
137 forward::dispatch(call)
138 }
139
140 fn progress(
141 app: pin::Pin<&Self>,
142 view: executor::raw::Progress<'_, '_, 'd>,
143 ) -> schedule::Progress<'d> {
144 <lending::raw::Pair<'_, 'd, H, T> as executor::raw::App<'d>>::progress(
145 lending::raw::Project::shared(app),
146 view,
147 )
148 }
149
150 fn stopping(
151 app: pin::Pin<&Self>,
152 view: executor::raw::Progress<'_, '_, 'd>,
153 ) -> schedule::Progress<'d> {
154 <lending::raw::Pair<'_, 'd, H, T> as executor::raw::App<'d>>::stopping(
155 lending::raw::Project::shared(app),
156 view,
157 )
158 }
159
160 fn shutdown<'call, 'turn, 'driver, 'owner>(
161 call: executor::raw::Shutdown<'call, 'turn, 'driver, 'owner, 'd, Self>,
162 ) -> executor::raw::Shutdown<'call, 'turn, 'driver, 'owner, 'd, Self>
163 where
164 'd: 'owner,
165 {
166 let (mut app, turn, driver) = call.into_parts();
167 let tail = app.as_mut().project().inner.project().tail;
168 let call = executor::raw::Shutdown::new(tail, turn, driver);
169 let (turn, driver) = forward::shutdown(call).into_drive();
170 let head = app.as_mut().project().inner.project().head;
171 let call = executor::raw::Shutdown::new(head, turn, driver);
172 let (turn, driver) = forward::shutdown(call).into_drive();
173 executor::raw::Shutdown::new(app, turn, driver)
174 }
175
176 fn finish<'call, 'finish, 'owner, 'epoch>(
177 call: executor::raw::Finish<'call, 'finish, 'owner, 'epoch, 'd, Self>,
178 ) -> executor::raw::Finish<'call, 'finish, 'owner, 'epoch, 'd, Self> {
179 let (mut app, install, finish) = call.into_parts();
180 let tail = app.as_mut().project().inner.project().tail;
181 let call = executor::raw::Finish::new(tail, install, finish);
182 let (install, finish) =
183 <lending::raw::Owner<mem::ManuallyDrop<T>, T> as executor::raw::Finishes<'d>>::call(
184 call,
185 )
186 .into_finish();
187 let mut head = app.as_mut().project().inner.project().head;
188 let _ = <lending::raw::Borrowed<'_, H> as executor::raw::App<'d>>::released(
189 executor::raw::Released::new(head.as_mut()),
190 );
191 let call = executor::raw::Finish::new(head, install, finish);
192 let (install, finish) =
193 <lending::raw::Borrowed<'_, H> as executor::raw::Finishes<'d>>::call(call)
194 .into_finish();
195 executor::raw::Finish::new(app, install, finish)
196 }
197}
198
199impl<'parent, 'd, H, T> Bound<'parent, 'd, H, T>
200where
201 H: executor::raw::App<'d>,
202 T: executor::raw::App<'d>,
203{
204 pub(crate) unsafe fn finish_tail<'call, 'finish, 'owner, 'epoch>(
207 call: executor::raw::Finish<'call, 'finish, 'owner, 'epoch, 'd, Self>,
208 plan: Option<<Self as executor::raw::Layout<'d>>::ParkPlan>,
209 ) -> (
210 lending::raw::Borrowed<'parent, H>,
211 Option<<H as executor::raw::Layout<'d>>::ParkPlan>,
212 ) {
213 let (mut app, install, finish) = call.into_parts();
214 let tail = app.as_mut().project().inner.project().tail;
215 let call = executor::raw::Finish::new(tail, install, finish);
216 let _ = <lending::raw::Owner<mem::ManuallyDrop<T>, T> as executor::raw::Finishes<'d>>::call(
217 call,
218 );
219 let head = app.as_mut().project().inner.project().head;
220 let head = unsafe { ptr::read(head.get_unchecked_mut()) };
223 (head, plan.and_then(|plan| plan.3))
224 }
225}
226
227unsafe impl<'d, H, T> executor::raw::Drain<'d> for Bound<'_, 'd, H, T>
230where
231 H: executor::raw::App<'d>,
232 T: executor::raw::Drain<'d>,
233{
234 fn begin(
235 self: pin::Pin<&mut Self>,
236 turn: schedule::Turn<'_, 'd>,
237 driver: &mut retained::Context<'_, '_, 'd>,
238 ) {
239 executor::raw::Drain::begin(self.project().inner, turn, driver);
240 }
241
242 fn progress(
243 self: pin::Pin<&Self>,
244 region: ®ion::Token<region::Identity<'d>>,
245 ) -> schedule::Progress<'d> {
246 executor::raw::Drain::progress(self.project_ref().inner, region)
247 }
248
249 fn force(
250 self: pin::Pin<&mut Self>,
251 turn: schedule::Turn<'_, 'd>,
252 driver: &mut retained::Context<'_, '_, 'd>,
253 ) {
254 executor::raw::Drain::force(self.project().inner, turn, driver);
255 }
256}
257
258const _: () = {
259 assert!(mem::size_of::<Bound<'_, '_, (), ()>>() == mem::size_of::<&mut ()>());
260 assert!(mem::align_of::<Bound<'_, '_, (), ()>>() == mem::align_of::<&mut ()>());
261 assert!(!mem::needs_drop::<Bound<'_, '_, (), ()>>());
262};