1use std::{mem, pin};
2
3use o3::{
4 alloc,
5 base::cell::region,
6 buffer::{
7 hold::limits,
8 resident::{Budget, Reuse},
9 },
10};
11
12use crate::{
13 BranchError, driver,
14 driver::{
15 life,
16 retained::flight,
17 route::{App, lease, queues},
18 schedule::{clock, clock::timer},
19 settings,
20 settings::{claim, errors},
21 },
22};
23
24mod cleanup;
25mod failure;
26mod mapping;
27pub mod path;
28mod release;
29mod removal;
30pub mod resident;
31mod scope;
32
33pub use cleanup::Cleanup;
34pub use failure::Failure;
35pub use mapping::Mapping;
36pub use release::Release;
37pub use removal::Removal;
38pub use scope::Scope;
39
40#[derive(Clone, Copy, Debug, PartialEq, Eq)]
41#[repr(transparent)]
42pub struct Address(*mut core::ffi::c_void);
43
44#[derive(Clone, Copy, Debug, PartialEq, Eq)]
45#[repr(transparent)]
46pub struct Bytes(usize);
47
48#[derive(Clone, Copy, Debug, PartialEq, Eq)]
49#[repr(transparent)]
50pub struct Count(usize);
51
52impl Address {
53 pub(crate) const fn new(address: *mut core::ffi::c_void) -> Self {
54 Self(address)
55 }
56}
57
58impl Bytes {
59 pub(crate) const fn new(bytes: usize) -> Self {
60 Self(bytes)
61 }
62}
63
64impl Count {
65 pub(crate) const fn new(count: usize) -> Self {
66 Self(count)
67 }
68}
69
70#[derive(Clone, Copy, Eq, PartialEq)]
72#[repr(transparent)]
73pub struct Resident(usize);
74
75#[derive(Clone, Copy, Debug, Eq, PartialEq)]
77pub enum Exhausted {
78 Domains { capacity: usize },
79 Retained { index: usize, cause: Reuse },
80}
81
82const _: () = assert!(size_of::<Exhausted>() == size_of::<usize>() * 4);
83
84impl Resident {
85 pub const fn bytes(bytes: usize) -> Self {
86 Self(bytes)
87 }
88
89 pub const fn from_limit(limit: limits::Bound) -> Self {
90 Self(limit.bytes())
91 }
92
93 const fn get(self) -> usize {
94 self.0
95 }
96}
97
98pub trait Path<Root, Leaf>: Copy
100where
101 Root: Plan,
102 Leaf: Plan,
103{
104 fn get<'life, 'p, 'd>(self, root: &'life Root::Output<'p, 'd>) -> &'life Leaf::Output<'p, 'd>
105 where
106 'd: 'p,
107 'p: 'life,
108 'd: 'life,
109 Self: 'd,
110 Root: 'd,
111 Leaf: 'd;
112}
113
114#[repr(transparent)]
120pub struct Context<'a, 'd>(pub(in crate::driver) &'a mut life::Local<'d>);
121
122impl<'a, 'd> Context<'a, 'd> {
123 pub(super) fn new(local: &'a mut life::Local<'d>) -> Self {
124 Self(local)
125 }
126
127 pub fn driver(&self) -> driver::Reference<'d> {
128 self.0.driver
129 }
130
131 pub fn receive(&self) -> settings::Receive {
133 self.0.driver.receive().layout()
134 }
135
136 pub fn region(&self) -> ®ion::Token<region::Identity<'d>> {
137 &self.0.region.0
138 }
139
140 pub fn state(&self) -> ®ion::Token<region::Identity<'d, 1>> {
141 &self.0.region.1
142 }
143
144 pub fn timer(&self) -> timer::Timer<'d> {
145 self.0.driver.timer()
146 }
147
148 pub fn clock(&self) -> clock::Clock<'_, 'd> {
149 self.0.driver.scheduler().clock()
150 }
151
152 pub fn allocator(&self) -> resident::Alloc<'d> {
154 self.0.resident
155 }
156
157 pub fn budget(&self, cap: Resident) -> Result<Budget<'d>, Exhausted> {
160 self.0.resident.try_budget(cap.get())
161 }
162
163 pub fn reborrow(&mut self) -> Context<'_, 'd> {
165 Context(&mut *self.0)
166 }
167
168 pub fn try_flights<Tags, const GROUPS: usize>(
170 self,
171 need: flight::Need<Tags, GROUPS>,
172 ) -> Result<flight::Prepared<'a, 'd, Tags, GROUPS>, alloc::Error> {
173 let Self(local) = self;
174 local.flights.try_prepare(need, local.driver)
175 }
176
177 pub fn try_reserve<B: App>(self) -> Result<lease::Claim<'d, B>, lease::Error> {
178 let Self(local) = self;
179 lease::Claim::try_new(local)
180 }
181
182 pub(in crate::driver) fn release(&mut self, retired: queues::Retired<'d>) {
183 lease::Registry::release(self.0, retired);
184 }
185}
186
187pub trait Plan {
192 type Output<'p, 'd>: 'p
193 where
194 Self: 'd,
195 'd: 'p;
196}
197
198#[repr(transparent)]
200pub struct Loan<'a, 'p: 'a, 'd: 'p, S: Plan + 'd> {
201 value: pin::Pin<&'a S::Output<'p, 'd>>,
202}
203
204impl<'a, 'p: 'a, 'd: 'p, S: Plan + 'd> Loan<'a, 'p, 'd, S> {
205 pub(in crate::driver) fn new(value: pin::Pin<&'a S::Output<'p, 'd>>) -> Self {
206 Self { value }
207 }
208
209 pub fn pinned(&self) -> pin::Pin<&'a S::Output<'p, 'd>> {
213 self.value
214 }
215}
216
217const _: () = {
218 assert!(mem::size_of::<Loan<'static, 'static, 'static, ()>>() == mem::size_of::<usize>());
219 assert!(mem::align_of::<Loan<'static, 'static, 'static, ()>>() == mem::align_of::<usize>());
220};
221
222pub trait Build: Plan {
224 type Error;
225
226 type Store<'d>
227 where
228 Self: 'd;
229
230 fn try_store<'d>(&self) -> Result<Self::Store<'d>, Self::Error>
231 where
232 Self: 'd;
233
234 fn try_build<'p, 'd>(
235 self,
236 store: &'p mut Self::Store<'d>,
237 ctx: Context<'_, 'd>,
238 ) -> Result<Self::Output<'p, 'd>, Self::Error>
239 where
240 Self: 'd,
241 'd: 'p;
242}
243
244pub trait Create: Plan {
246 type Error;
247
248 fn try_build<'p, 'd>(self, ctx: Context<'_, 'd>) -> Result<Self::Output<'p, 'd>, Self::Error>
249 where
250 Self: 'd,
251 'd: 'p;
252}
253
254pub trait Claimless: Plan {}
256
257pub trait Direct: Plan {
259 fn build<'p, 'd>(self) -> Self::Output<'p, 'd>
260 where
261 Self: 'd,
262 'd: 'p;
263}
264
265#[repr(transparent)]
266pub struct Value<T>(T);
267
268impl<T> Value<T> {
269 pub const fn new(value: T) -> Self {
270 Self(value)
271 }
272}
273
274impl<T> Plan for Value<T> {
275 type Output<'p, 'd>
276 = T
277 where
278 'd: 'p,
279 Self: 'd;
280}
281
282impl<T> Claimless for Value<T> {}
283
284impl<T> Direct for Value<T> {
285 fn build<'p, 'd>(self) -> Self::Output<'p, 'd>
286 where
287 'd: 'p,
288 Self: 'd,
289 {
290 self.0
291 }
292}
293
294impl Plan for () {
295 type Output<'p, 'd>
296 = ()
297 where
298 'd: 'p,
299 Self: 'd;
300}
301
302impl Claimless for () {}
303
304impl Direct for () {
305 fn build<'p, 'd>(self) -> Self::Output<'p, 'd>
306 where
307 'd: 'p,
308 Self: 'd,
309 {
310 self
311 }
312}
313
314impl<A: Plan, B: Plan> Plan for (A, B) {
315 type Output<'p, 'd>
316 = (A::Output<'p, 'd>, B::Output<'p, 'd>)
317 where
318 'd: 'p,
319 Self: 'd;
320}
321
322impl<A: Build, B: Build> Build for (A, B) {
323 type Error = BranchError<A::Error, B::Error>;
324 type Store<'d>
325 = (A::Store<'d>, B::Store<'d>)
326 where
327 Self: 'd;
328
329 fn try_store<'d>(&self) -> Result<Self::Store<'d>, Self::Error>
330 where
331 Self: 'd,
332 {
333 let first = self.0.try_store().map_err(BranchError::First)?;
334 let second = self.1.try_store().map_err(BranchError::Second)?;
335 Ok((first, second))
336 }
337
338 fn try_build<'p, 'd>(
339 self,
340 store: &'p mut Self::Store<'d>,
341 mut ctx: Context<'_, 'd>,
342 ) -> Result<Self::Output<'p, 'd>, Self::Error>
343 where
344 'd: 'p,
345 Self: 'd,
346 {
347 let (first, second) = self;
348 let first = first
349 .try_build(&mut store.0, ctx.reborrow())
350 .map_err(BranchError::First)?;
351 let second = second
352 .try_build(&mut store.1, ctx)
353 .map_err(BranchError::Second)?;
354 Ok((first, second))
355 }
356}
357
358impl<A: Claimless, B: Claimless> Claimless for (A, B) {}
359
360impl<A: Direct, B: Direct> Direct for (A, B) {
361 fn build<'p, 'd>(self) -> Self::Output<'p, 'd>
362 where
363 'd: 'p,
364 Self: 'd,
365 {
366 let first = Direct::build(self.0);
367 let second = Direct::build(self.1);
368 (first, second)
369 }
370}
371
372const _: () = {
373 assert!(std::mem::size_of::<Context<'static, 'static>>() == std::mem::size_of::<usize>());
374 assert!(std::mem::align_of::<Context<'static, 'static>>() == std::mem::align_of::<usize>());
375 assert!(std::mem::size_of::<Value<usize>>() == std::mem::size_of::<usize>());
376 assert!(std::mem::align_of::<Value<usize>>() == std::mem::align_of::<usize>());
377 assert!(std::mem::needs_drop::<Value<String>>() == std::mem::needs_drop::<String>());
378};
379
380#[repr(transparent)]
382pub struct With<F, T>((F, T));
383
384impl<F, T> With<F, T> {
385 pub const fn new(plan: F, value: T) -> Self {
386 Self((plan, value))
387 }
388}
389
390impl<F, T> settings::Resource for With<F, T>
391where
392 F: settings::Resource,
393{
394 fn include_in(&self, needs: claim::Needs) -> Result<claim::Needs, errors::Claim> {
395 self.0.0.include_in(needs)
396 }
397}
398
399impl<F, T> Plan for With<F, T>
400where
401 F: Plan,
402{
403 type Output<'p, 'd>
404 = (F::Output<'p, 'd>, T)
405 where
406 'd: 'p,
407 Self: 'd;
408}
409
410impl<F, T> Build for With<F, T>
411where
412 F: Build,
413{
414 type Error = F::Error;
415 type Store<'d>
416 = F::Store<'d>
417 where
418 Self: 'd;
419
420 fn try_store<'d>(&self) -> Result<Self::Store<'d>, Self::Error>
421 where
422 Self: 'd,
423 {
424 self.0.0.try_store()
425 }
426
427 fn try_build<'p, 'd>(
428 self,
429 store: &'p mut Self::Store<'d>,
430 ctx: Context<'_, 'd>,
431 ) -> Result<Self::Output<'p, 'd>, Self::Error>
432 where
433 'd: 'p,
434 Self: 'd,
435 {
436 let (plan, value) = self.0;
437 Ok((plan.try_build(store, ctx)?, value))
438 }
439}
440
441impl<F: Direct, T> Direct for With<F, T> {
442 fn build<'p, 'd>(self) -> Self::Output<'p, 'd>
443 where
444 'd: 'p,
445 Self: 'd,
446 {
447 let (plan, value) = self.0;
448 (plan.build(), value)
449 }
450}
451
452impl<F: Claimless, T> Claimless for With<F, T> {}
453
454const _: () = {
455 assert!(mem::size_of::<With<usize, u8>>() == mem::size_of::<(usize, u8)>());
456 assert!(mem::align_of::<With<usize, u8>>() == mem::align_of::<(usize, u8)>());
457 assert!(mem::needs_drop::<With<String, ()>>() == mem::needs_drop::<String>());
458};