drivers/standard_library/
executor.rs1use embassy_executor::{Spawner, raw};
2use std::boxed::Box;
3use std::marker::PhantomData;
4use std::sync::atomic::AtomicBool;
5use std::sync::{Condvar, Mutex};
6
7pub struct Executor {
9 inner: raw::Executor,
10 not_send: PhantomData<*mut ()>,
11 signaler: &'static Signaler,
12 stop: AtomicBool,
13}
14
15impl Default for Executor {
16 fn default() -> Self {
17 Self::new()
18 }
19}
20
21impl Executor {
22 pub fn new() -> Self {
24 let signaler = Box::leak(Box::new(Signaler::new()));
25 Self {
26 inner: raw::Executor::new(signaler as *mut Signaler as *mut ()),
27 not_send: PhantomData,
28 signaler,
29 stop: AtomicBool::new(false),
30 }
31 }
32
33 pub fn stop(&self) {
34 self.stop.store(true, std::sync::atomic::Ordering::SeqCst);
35 self.signaler.signal();
36 }
37
38 pub fn spawner(&'static self) -> Spawner {
40 self.inner.spawner()
41 }
42
43 pub fn run(&'static self, init: impl FnOnce(Spawner, &'static Self)) {
62 init(self.inner.spawner(), self);
63
64 while !self.stop.load(std::sync::atomic::Ordering::SeqCst) {
65 unsafe { self.inner.poll() };
66 self.signaler.wait();
67 }
68 }
69}
70
71struct Signaler {
72 mutex: Mutex<bool>,
73 condvar: Condvar,
74}
75
76impl Signaler {
77 fn new() -> Self {
78 Self {
79 mutex: Mutex::new(false),
80 condvar: Condvar::new(),
81 }
82 }
83
84 fn wait(&self) {
85 let mut signaled = self.mutex.lock().unwrap();
86 while !*signaled {
87 signaled = self.condvar.wait(signaled).unwrap();
88 }
89 *signaled = false;
90 }
91
92 fn signal(&self) {
93 let mut signaled = self.mutex.lock().unwrap();
94 *signaled = true;
95 self.condvar.notify_one();
96 }
97}
98
99#[macro_export]
100macro_rules! instantiate_static_executor {
101 () => {{
102 static mut __EXECUTOR: Option<$crate::standard_library::executor::Executor> = None;
103
104 unsafe {
105 if __EXECUTOR.is_none() {
106 __EXECUTOR = Some($crate::standard_library::executor::Executor::new());
107 }
108 __EXECUTOR.as_mut().expect("Executor is not initialized")
109 }
110 }};
111}
112
113pub use instantiate_static_executor;