aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/src/arch
diff options
context:
space:
mode:
authorDániel Buga <[email protected]>2023-08-14 08:57:14 +0200
committerDániel Buga <[email protected]>2023-08-14 09:00:08 +0200
commitf6007869bffd3ed4f48e74222dc40d11c7c87ec0 (patch)
treebd8e1afe8d0a959a52ddcb75bdc30988a7d1615e /embassy-executor/src/arch
parent454a7cbf4c0eb3a4e651e7da5512ec49ff7d4050 (diff)
Remove the Pender enum
Diffstat (limited to 'embassy-executor/src/arch')
-rw-r--r--embassy-executor/src/arch/cortex_m.rs103
-rw-r--r--embassy-executor/src/arch/riscv32.rs10
-rw-r--r--embassy-executor/src/arch/std.rs10
-rw-r--r--embassy-executor/src/arch/wasm.rs6
-rw-r--r--embassy-executor/src/arch/xtensa.rs8
5 files changed, 84 insertions, 53 deletions
diff --git a/embassy-executor/src/arch/cortex_m.rs b/embassy-executor/src/arch/cortex_m.rs
index a29e5b23e..7f8a97ef1 100644
--- a/embassy-executor/src/arch/cortex_m.rs
+++ b/embassy-executor/src/arch/cortex_m.rs
@@ -1,28 +1,84 @@
1#[cfg(feature = "executor-thread")] 1#[cfg(feature = "executor-thread")]
2pub use thread::*; 2pub use thread::*;
3 3
4use crate::raw::PenderContext;
5
6#[cfg(feature = "executor-interrupt")]
7
8/// # Safety
9///
10/// `irq` must be a valid interrupt request number
11unsafe fn nvic_pend(irq: u16) {
12 use cortex_m::interrupt::InterruptNumber;
13
14 #[derive(Clone, Copy)]
15 struct Irq(u16);
16 unsafe impl InterruptNumber for Irq {
17 fn number(self) -> u16 {
18 self.0
19 }
20 }
21
22 let irq = Irq(irq);
23
24 // STIR is faster, but is only available in v7 and higher.
25 #[cfg(not(armv6m))]
26 {
27 let mut nvic: cortex_m::peripheral::NVIC = unsafe { core::mem::transmute(()) };
28 nvic.request(irq);
29 }
30
31 #[cfg(armv6m)]
32 cortex_m::peripheral::NVIC::pend(irq);
33}
34
35#[cfg(all(feature = "executor-thread", feature = "executor-interrupt"))]
36#[export_name = "__pender"]
37fn __pender(context: PenderContext) {
38 unsafe {
39 // Safety: `context` is either `usize::MAX` created by `Executor::run`, or a valid interrupt
40 // request number given to `InterruptExecutor::start`.
41 if context as usize == usize::MAX {
42 core::arch::asm!("sev")
43 } else {
44 nvic_pend(context as u16)
45 }
46 }
47}
48
49#[cfg(all(feature = "executor-thread", not(feature = "executor-interrupt")))]
50#[export_name = "__pender"]
51fn __pender(_context: PenderContext) {
52 unsafe { core::arch::asm!("sev") }
53}
54
55#[cfg(all(not(feature = "executor-thread"), feature = "executor-interrupt"))]
56#[export_name = "__pender"]
57fn __pender(context: PenderContext) {
58 unsafe {
59 // Safety: `context` is the same value we passed to `InterruptExecutor::start`, which must
60 // be a valid interrupt request number.
61 nvic_pend(context as u16)
62 }
63}
64
4#[cfg(feature = "executor-thread")] 65#[cfg(feature = "executor-thread")]
5mod thread { 66mod thread {
6 67
7 #[cfg(feature = "nightly")] 68 #[cfg(feature = "nightly")]
8 pub use embassy_macros::main_cortex_m as main; 69 pub use embassy_macros::main_cortex_m as main;
9 70
10 use crate::raw::OpaqueThreadContext; 71 use crate::raw::PenderContext;
11 use crate::thread::ThreadContext; 72 use crate::thread::ThreadContext;
12 73
13 #[export_name = "__thread_mode_pender"]
14 fn __thread_mode_pender(_context: OpaqueThreadContext) {
15 unsafe { core::arch::asm!("sev") }
16 }
17
18 /// TODO 74 /// TODO
19 // Name pending 75 // Name pending
20 #[derive(Default)] // Default enables Executor::new 76 #[derive(Default)] // Default enables Executor::new
21 pub struct Context; 77 pub struct Context;
22 78
23 impl ThreadContext for Context { 79 impl ThreadContext for Context {
24 fn context(&self) -> OpaqueThreadContext { 80 fn context(&self) -> PenderContext {
25 OpaqueThreadContext(0) 81 usize::MAX
26 } 82 }
27 83
28 fn wait(&mut self) { 84 fn wait(&mut self) {
@@ -35,7 +91,6 @@ mod thread {
35 pub type Executor = crate::thread::ThreadModeExecutor<Context>; 91 pub type Executor = crate::thread::ThreadModeExecutor<Context>;
36} 92}
37 93
38// None of this has to be public, I guess?
39#[cfg(feature = "executor-interrupt")] 94#[cfg(feature = "executor-interrupt")]
40pub use interrupt::*; 95pub use interrupt::*;
41#[cfg(feature = "executor-interrupt")] 96#[cfg(feature = "executor-interrupt")]
@@ -44,23 +99,14 @@ mod interrupt {
44 use cortex_m::peripheral::NVIC; 99 use cortex_m::peripheral::NVIC;
45 100
46 use crate::interrupt::InterruptContext; 101 use crate::interrupt::InterruptContext;
47 use crate::raw::OpaqueInterruptContext; 102 use crate::raw::PenderContext;
48
49 #[derive(Clone, Copy)]
50 struct CortexMInterruptContext(u16);
51
52 unsafe impl cortex_m::interrupt::InterruptNumber for CortexMInterruptContext {
53 fn number(self) -> u16 {
54 self.0
55 }
56 }
57 103
58 impl<T> InterruptContext for T 104 impl<T> InterruptContext for T
59 where 105 where
60 T: InterruptNumber, 106 T: InterruptNumber,
61 { 107 {
62 fn context(&self) -> OpaqueInterruptContext { 108 fn context(&self) -> PenderContext {
63 OpaqueInterruptContext(self.number() as usize) 109 self.number() as usize
64 } 110 }
65 111
66 fn enable(&self) { 112 fn enable(&self) {
@@ -68,21 +114,6 @@ mod interrupt {
68 } 114 }
69 } 115 }
70 116
71 #[export_name = "__interrupt_mode_pender"]
72 fn __interrupt_mode_pender(interrupt: OpaqueInterruptContext) {
73 let interrupt = CortexMInterruptContext(unsafe { core::mem::transmute::<_, usize>(interrupt) as u16 });
74
75 // STIR is faster, but is only available in v7 and higher.
76 #[cfg(not(armv6m))]
77 {
78 let mut nvic: NVIC = unsafe { core::mem::transmute(()) };
79 nvic.request(interrupt);
80 }
81
82 #[cfg(armv6m)]
83 NVIC::pend(interrupt);
84 }
85
86 /// TODO 117 /// TODO
87 // Type alias for backwards compatibility 118 // Type alias for backwards compatibility
88 pub type InterruptExecutor = crate::interrupt::InterruptModeExecutor; 119 pub type InterruptExecutor = crate::interrupt::InterruptModeExecutor;
diff --git a/embassy-executor/src/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs
index 976e7bcb3..886056e84 100644
--- a/embassy-executor/src/arch/riscv32.rs
+++ b/embassy-executor/src/arch/riscv32.rs
@@ -10,14 +10,14 @@ mod thread {
10 #[cfg(feature = "nightly")] 10 #[cfg(feature = "nightly")]
11 pub use embassy_macros::main_riscv as main; 11 pub use embassy_macros::main_riscv as main;
12 12
13 use crate::raw::OpaqueThreadContext; 13 use crate::raw::PenderContext;
14 use crate::thread::ThreadContext; 14 use crate::thread::ThreadContext;
15 15
16 /// global atomic used to keep track of whether there is work to do since sev() is not available on RISCV 16 /// global atomic used to keep track of whether there is work to do since sev() is not available on RISCV
17 static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false); 17 static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false);
18 18
19 #[export_name = "__thread_mode_pender"] 19 #[export_name = "__pender"]
20 fn __thread_mode_pender(_context: OpaqueThreadContext) { 20 fn __thread_mode_pender(_context: PenderContext) {
21 SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst); 21 SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst);
22 } 22 }
23 23
@@ -27,8 +27,8 @@ mod thread {
27 pub struct Context; 27 pub struct Context;
28 28
29 impl ThreadContext for Context { 29 impl ThreadContext for Context {
30 fn context(&self) -> OpaqueThreadContext { 30 fn context(&self) -> PenderContext {
31 OpaqueThreadContext(0) 31 0
32 } 32 }
33 33
34 fn wait(&mut self) { 34 fn wait(&mut self) {
diff --git a/embassy-executor/src/arch/std.rs b/embassy-executor/src/arch/std.rs
index ceaa5c7ab..d2a069d1c 100644
--- a/embassy-executor/src/arch/std.rs
+++ b/embassy-executor/src/arch/std.rs
@@ -10,7 +10,7 @@ mod thread {
10 #[cfg(feature = "nightly")] 10 #[cfg(feature = "nightly")]
11 pub use embassy_macros::main_std as main; 11 pub use embassy_macros::main_std as main;
12 12
13 use crate::raw::OpaqueThreadContext; 13 use crate::raw::PenderContext;
14 use crate::thread::ThreadContext; 14 use crate::thread::ThreadContext;
15 15
16 /// TODO 16 /// TODO
@@ -28,8 +28,8 @@ mod thread {
28 } 28 }
29 29
30 impl ThreadContext for Context { 30 impl ThreadContext for Context {
31 fn context(&self) -> OpaqueThreadContext { 31 fn context(&self) -> PenderContext {
32 OpaqueThreadContext(self.signaler as *const _ as usize) 32 self.signaler as *const _ as usize
33 } 33 }
34 34
35 fn wait(&mut self) { 35 fn wait(&mut self) {
@@ -37,8 +37,8 @@ mod thread {
37 } 37 }
38 } 38 }
39 39
40 #[export_name = "__thread_mode_pender"] 40 #[export_name = "__pender"]
41 fn __thread_mode_pender(context: OpaqueThreadContext) { 41 fn __pender(context: PenderContext) {
42 let signaler: &'static Signaler = unsafe { std::mem::transmute(context) }; 42 let signaler: &'static Signaler = unsafe { std::mem::transmute(context) };
43 signaler.signal() 43 signaler.signal()
44 } 44 }
diff --git a/embassy-executor/src/arch/wasm.rs b/embassy-executor/src/arch/wasm.rs
index c393722b2..634f48d1a 100644
--- a/embassy-executor/src/arch/wasm.rs
+++ b/embassy-executor/src/arch/wasm.rs
@@ -14,11 +14,11 @@ mod thread {
14 use wasm_bindgen::prelude::*; 14 use wasm_bindgen::prelude::*;
15 15
16 use crate::raw::util::UninitCell; 16 use crate::raw::util::UninitCell;
17 use crate::raw::{OpaqueThreadContext, Pender}; 17 use crate::raw::PenderContext;
18 use crate::{raw, Spawner}; 18 use crate::{raw, Spawner};
19 19
20 #[export_name = "__thread_mode_pender"] 20 #[export_name = "__thread_mode_pender"]
21 fn __thread_mode_pender(context: OpaqueThreadContext) { 21 fn __thread_mode_pender(context: PenderContext) {
22 let signaler: &'static WasmContext = unsafe { std::mem::transmute(context) }; 22 let signaler: &'static WasmContext = unsafe { std::mem::transmute(context) };
23 let _ = signaler.promise.then(unsafe { signaler.closure.as_mut() }); 23 let _ = signaler.promise.then(unsafe { signaler.closure.as_mut() });
24 } 24 }
@@ -49,7 +49,7 @@ mod thread {
49 pub fn new() -> Self { 49 pub fn new() -> Self {
50 let ctx = &*Box::leak(Box::new(WasmContext::new())); 50 let ctx = &*Box::leak(Box::new(WasmContext::new()));
51 Self { 51 Self {
52 inner: raw::Executor::new(Pender::Thread(OpaqueThreadContext(ctx as *const _ as usize))), 52 inner: raw::Executor::new(ctx as *const _ as usize),
53 ctx, 53 ctx,
54 not_send: PhantomData, 54 not_send: PhantomData,
55 } 55 }
diff --git a/embassy-executor/src/arch/xtensa.rs b/embassy-executor/src/arch/xtensa.rs
index 28abf352c..3986c6c19 100644
--- a/embassy-executor/src/arch/xtensa.rs
+++ b/embassy-executor/src/arch/xtensa.rs
@@ -8,14 +8,14 @@ mod thread {
8 use core::marker::PhantomData; 8 use core::marker::PhantomData;
9 use core::sync::atomic::{AtomicBool, Ordering}; 9 use core::sync::atomic::{AtomicBool, Ordering};
10 10
11 use crate::raw::OpaqueThreadContext; 11 use crate::raw::PenderContext;
12 use crate::thread::ThreadContext; 12 use crate::thread::ThreadContext;
13 13
14 /// global atomic used to keep track of whether there is work to do since sev() is not available on Xtensa 14 /// global atomic used to keep track of whether there is work to do since sev() is not available on Xtensa
15 static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false); 15 static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false);
16 16
17 #[export_name = "__thread_mode_pender"] 17 #[export_name = "__thread_mode_pender"]
18 fn __thread_mode_pender(_context: OpaqueThreadContext) { 18 fn __thread_mode_pender(_context: PenderContext) {
19 SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst); 19 SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst);
20 } 20 }
21 21
@@ -25,8 +25,8 @@ mod thread {
25 pub struct Context; 25 pub struct Context;
26 26
27 impl ThreadContext for Context { 27 impl ThreadContext for Context {
28 fn context(&self) -> OpaqueThreadContext { 28 fn context(&self) -> PenderContext {
29 OpaqueThreadContext(0) 29 0
30 } 30 }
31 31
32 fn wait(&mut self) { 32 fn wait(&mut self) {