diff options
| author | Dániel Buga <[email protected]> | 2023-08-14 15:35:22 +0200 |
|---|---|---|
| committer | Dániel Buga <[email protected]> | 2023-08-14 15:41:53 +0200 |
| commit | 986a63ebb8611a4dc7c6b14e03146286942ec8e7 (patch) | |
| tree | f6f963c33fde5397eeeb714d3823a5db089c5991 /embassy-executor/src/arch/std.rs | |
| parent | 4c4b12c307bf77516299eb73f9da00ef777b9814 (diff) | |
Remove the non-specific thread-mode executor
Diffstat (limited to 'embassy-executor/src/arch/std.rs')
| -rw-r--r-- | embassy-executor/src/arch/std.rs | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/embassy-executor/src/arch/std.rs b/embassy-executor/src/arch/std.rs index d55de118d..f490084d6 100644 --- a/embassy-executor/src/arch/std.rs +++ b/embassy-executor/src/arch/std.rs | |||
| @@ -5,44 +5,66 @@ compile_error!("`executor-interrupt` is not supported with `arch-std`."); | |||
| 5 | pub use thread::*; | 5 | pub use thread::*; |
| 6 | #[cfg(feature = "executor-thread")] | 6 | #[cfg(feature = "executor-thread")] |
| 7 | mod thread { | 7 | mod thread { |
| 8 | use std::marker::PhantomData; | ||
| 8 | use std::sync::{Condvar, Mutex}; | 9 | use std::sync::{Condvar, Mutex}; |
| 9 | 10 | ||
| 10 | #[cfg(feature = "nightly")] | 11 | #[cfg(feature = "nightly")] |
| 11 | pub use embassy_macros::main_std as main; | 12 | pub use embassy_macros::main_std as main; |
| 12 | 13 | ||
| 13 | use crate::raw::PenderContext; | 14 | use crate::{raw, Spawner}; |
| 14 | use crate::thread::ThreadContext; | ||
| 15 | 15 | ||
| 16 | /// TODO | 16 | #[export_name = "__pender"] |
| 17 | // Name pending | 17 | fn __pender(context: crate::raw::PenderContext) { |
| 18 | pub struct Context { | 18 | let signaler: &'static Signaler = unsafe { std::mem::transmute(context) }; |
| 19 | signaler.signal() | ||
| 20 | } | ||
| 21 | |||
| 22 | /// Single-threaded std-based executor. | ||
| 23 | pub struct Executor { | ||
| 24 | inner: raw::Executor, | ||
| 25 | not_send: PhantomData<*mut ()>, | ||
| 19 | signaler: &'static Signaler, | 26 | signaler: &'static Signaler, |
| 20 | } | 27 | } |
| 21 | 28 | ||
| 22 | impl Default for Context { | 29 | impl Executor { |
| 23 | fn default() -> Self { | 30 | /// Create a new Executor. |
| 31 | pub fn new() -> Self { | ||
| 32 | let signaler = &*Box::leak(Box::new(Signaler::new())); | ||
| 24 | Self { | 33 | Self { |
| 25 | signaler: &*Box::leak(Box::new(Signaler::new())), | 34 | inner: raw::Executor::new(unsafe { std::mem::transmute(signaler) }), |
| 35 | not_send: PhantomData, | ||
| 36 | signaler, | ||
| 26 | } | 37 | } |
| 27 | } | 38 | } |
| 28 | } | ||
| 29 | 39 | ||
| 30 | impl ThreadContext for Context { | 40 | /// Run the executor. |
| 31 | fn context(&self) -> PenderContext { | 41 | /// |
| 32 | unsafe { core::mem::transmute(self.signaler) } | 42 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on |
| 33 | } | 43 | /// this executor. Use it to spawn the initial task(s). After `init` returns, |
| 44 | /// the executor starts running the tasks. | ||
| 45 | /// | ||
| 46 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | ||
| 47 | /// for example by passing it as an argument to the initial tasks. | ||
| 48 | /// | ||
| 49 | /// This function requires `&'static mut self`. This means you have to store the | ||
| 50 | /// Executor instance in a place where it'll live forever and grants you mutable | ||
| 51 | /// access. There's a few ways to do this: | ||
| 52 | /// | ||
| 53 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | ||
| 54 | /// - a `static mut` (unsafe) | ||
| 55 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | ||
| 56 | /// | ||
| 57 | /// This function never returns. | ||
| 58 | pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { | ||
| 59 | init(self.inner.spawner()); | ||
| 34 | 60 | ||
| 35 | fn wait(&mut self) { | 61 | loop { |
| 36 | self.signaler.wait() | 62 | unsafe { self.inner.poll() }; |
| 63 | self.signaler.wait() | ||
| 64 | } | ||
| 37 | } | 65 | } |
| 38 | } | 66 | } |
| 39 | 67 | ||
| 40 | #[export_name = "__pender"] | ||
| 41 | fn __pender(context: PenderContext) { | ||
| 42 | let signaler: &'static Signaler = unsafe { std::mem::transmute(context) }; | ||
| 43 | signaler.signal() | ||
| 44 | } | ||
| 45 | |||
| 46 | struct Signaler { | 68 | struct Signaler { |
| 47 | mutex: Mutex<bool>, | 69 | mutex: Mutex<bool>, |
| 48 | condvar: Condvar, | 70 | condvar: Condvar, |
| @@ -70,8 +92,4 @@ mod thread { | |||
| 70 | self.condvar.notify_one(); | 92 | self.condvar.notify_one(); |
| 71 | } | 93 | } |
| 72 | } | 94 | } |
| 73 | |||
| 74 | /// TODO | ||
| 75 | // Type alias for backwards compatibility | ||
| 76 | pub type Executor = crate::thread::ThreadModeExecutor<Context>; | ||
| 77 | } | 95 | } |
