1
+ //! An experimental runtime for an async-await style task system.
2
+
1
3
use crate :: mpsc_queue:: { PopResult , Queue } ;
2
4
use alloc:: {
3
5
collections:: BTreeMap ,
@@ -14,6 +16,8 @@ use futures::{
14
16
task:: { LocalSpawn , Poll , Spawn , SpawnError } ,
15
17
} ;
16
18
19
+ /// An executor that schedules tasks round-robin, and executes an idle_task
20
+ /// if no task is ready to execute.
17
21
pub struct Executor {
18
22
tasks : BTreeMap < TaskId , Pin < Box < LocalFutureObj < ' static , ( ) > > > > ,
19
23
woken_tasks : Arc < Queue < TaskId > > ,
@@ -35,6 +39,7 @@ impl LocalSpawn for Executor {
35
39
}
36
40
37
41
impl Executor {
42
+ /// Creates a new executor.
38
43
pub fn new ( ) -> Self {
39
44
Executor {
40
45
tasks : BTreeMap :: new ( ) ,
@@ -51,6 +56,9 @@ impl Executor {
51
56
self . woken_tasks . push ( id) ;
52
57
}
53
58
59
+ /// Sets the specified task as idle task.
60
+ ///
61
+ /// It will be polled whenever there is no ready-to-run task in the queue.
54
62
pub fn set_idle_task < Fut > ( & mut self , future : Fut )
55
63
where
56
64
Fut : Future < Output = !> + ' static ,
@@ -59,6 +67,8 @@ impl Executor {
59
67
self . idle_task = Some ( future_obj) ;
60
68
}
61
69
70
+ /// Poll all tasks that are ready to run, until no ready tasks exist. Then poll the idle task
71
+ /// once and return.
62
72
pub fn run ( & mut self ) {
63
73
match self . woken_tasks . pop ( ) {
64
74
PopResult :: Data ( task_id) => {
@@ -119,14 +129,24 @@ impl Wake for NoOpWaker {
119
129
fn wake ( _arc_self : & Arc < Self > ) { }
120
130
}
121
131
122
- // TODO document, check behavior
132
+ /// This stream can be used by tasks that want to run when the CPU is idle.
133
+ ///
134
+ /// It works by alternately returning `Poll::Ready` and `Poll::Pending` from `poll_next`, starting
135
+ /// with `Poll::Pending`. When returning `Poll::Pending` it sends the Waker to the
136
+ /// `idle_waker_sink` (passed on construction). The idle task polls the other end of this sink and
137
+ /// wakes all received tasks when it runs.
138
+ // TODO is the behavior correct?
123
139
#[ derive( Debug , Clone ) ]
124
140
pub struct IdleStream {
125
141
idle : bool ,
126
142
idle_waker_sink : mpsc:: UnboundedSender < LocalWaker > ,
127
143
}
128
144
129
145
impl IdleStream {
146
+ /// Creates a new IdleStream with the passed sending end of an idle stream.
147
+ ///
148
+ /// The idle task should wake the tasks received from the receiving end
149
+ /// of the idle stream, thereby waking the tasks on idle.
130
150
pub fn new ( idle_waker_sink : mpsc:: UnboundedSender < LocalWaker > ) -> Self {
131
151
IdleStream {
132
152
idle_waker_sink,
0 commit comments