Skip to main content

dope_runtime/executor/
root.rs

1use std::{pin, task};
2
3use dope_core::driver::{
4    self,
5    schedule::{app, ready},
6};
7
8/// Runtime poll capability tying one exact root and driver to a poll.
9pub struct Context<'poll, 'd: 'poll, R> {
10    root: pin::Pin<&'poll mut R>,
11    wake: ready::Target<'d>,
12    work: app::Work<'poll, 'd>,
13    driver: driver::Context<'poll, 'd>,
14}
15
16/// Remaining application-lane credits for one root poll.
17#[derive(Clone, Copy)]
18pub struct Budget<'poll, 'd> {
19    wake: ready::Target<'d>,
20    work: app::Work<'poll, 'd>,
21}
22
23impl<'poll, 'd: 'poll, R> Context<'poll, 'd, R> {
24    pub(crate) fn new(
25        root: pin::Pin<&'poll mut R>,
26        wake: ready::Target<'d>,
27        work: app::Work<'poll, 'd>,
28        driver: driver::Context<'poll, 'd>,
29    ) -> Self {
30        Self {
31            root,
32            wake,
33            work,
34            driver,
35        }
36    }
37
38    pub fn into_parts(
39        self,
40    ) -> (
41        pin::Pin<&'poll mut R>,
42        ready::Target<'d>,
43        app::Work<'poll, 'd>,
44        driver::Context<'poll, 'd>,
45    ) {
46        (self.root, self.wake, self.work, self.driver)
47    }
48
49    pub fn into_poll(
50        self,
51    ) -> (
52        pin::Pin<&'poll mut R>,
53        Budget<'poll, 'd>,
54        driver::Context<'poll, 'd>,
55    ) {
56        (self.root, Budget::new(self.wake, self.work), self.driver)
57    }
58}
59
60impl<'poll, 'd> Budget<'poll, 'd> {
61    pub(crate) const fn new(wake: ready::Target<'d>, work: app::Work<'poll, 'd>) -> Self {
62        Self { wake, work }
63    }
64
65    pub fn target(self) -> ready::Target<'d> {
66        self.wake
67    }
68
69    /// Reserves one more application transition, requeueing the root when its
70    /// current application-lane share is exhausted.
71    pub fn try_continue(self) -> Option<app::Permit<'poll, 'd>> {
72        let permit = self.work.permit();
73        if permit.is_none() {
74            self.wake.wake();
75        }
76        permit
77    }
78}
79
80/// Transient pinned control-flow root.
81/// Driver authority retains the application through terminal quiescence.
82pub trait Root<'d>: Sized {
83    type Output;
84    fn poll(context: Context<'_, 'd, Self>) -> task::Poll<Self::Output>;
85}