1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use super::{super::task, with_executor_as, Executor};
use core::{cell::UnsafeCell, future::Future, marker::Sync};
pub fn run<T>(future: impl Future<Output = T>) -> T {
let executor = SerialExecutor(UnsafeCell::new(Runtime {
run_queue: task::List::default(),
}));
with_executor_as(&executor, move |executor| {
let mut future = task::FutureTask::new(task::Priority::Normal, future);
if future.resume().is_ready() {
return future.into_output().unwrap();
}
while let Some(task) = executor.poll() {
task.resume();
}
debug_assert!(future.resume().is_ready());
future.into_output().unwrap()
})
}
struct Runtime {
run_queue: task::List,
}
struct SerialExecutor(UnsafeCell<Runtime>);
unsafe impl Sync for SerialExecutor {}
impl SerialExecutor {
pub fn poll<'a>(&self) -> Option<&'a mut task::Task> {
let runtime = unsafe { &mut *self.0.get() };
runtime.run_queue.pop()
}
}
impl Executor for SerialExecutor {
fn schedule(&self, task: &mut task::Task) {
let mut list = task::PriorityList::default();
list.push(task);
let runtime = unsafe { &mut *self.0.get() };
runtime.run_queue.push(&list);
}
}