aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/src
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-executor/src')
-rw-r--r--embassy-executor/src/lib.rs1
-rw-r--r--embassy-executor/src/raw/waker.rs25
2 files changed, 26 insertions, 0 deletions
diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs
index 6a2e493a2..553ed76d3 100644
--- a/embassy-executor/src/lib.rs
+++ b/embassy-executor/src/lib.rs
@@ -1,4 +1,5 @@
1#![cfg_attr(not(any(feature = "arch-std", feature = "arch-wasm")), no_std)] 1#![cfg_attr(not(any(feature = "arch-std", feature = "arch-wasm")), no_std)]
2#![cfg_attr(feature = "nightly", feature(waker_getters))]
2#![allow(clippy::new_without_default)] 3#![allow(clippy::new_without_default)]
3#![doc = include_str!("../README.md")] 4#![doc = include_str!("../README.md")]
4#![warn(missing_docs)] 5#![warn(missing_docs)]
diff --git a/embassy-executor/src/raw/waker.rs b/embassy-executor/src/raw/waker.rs
index 522853e34..fe64456e1 100644
--- a/embassy-executor/src/raw/waker.rs
+++ b/embassy-executor/src/raw/waker.rs
@@ -32,6 +32,7 @@ pub(crate) unsafe fn from_task(p: TaskRef) -> Waker {
32/// # Panics 32/// # Panics
33/// 33///
34/// Panics if the waker is not created by the Embassy executor. 34/// Panics if the waker is not created by the Embassy executor.
35#[cfg(not(feature = "nightly"))]
35pub fn task_from_waker(waker: &Waker) -> TaskRef { 36pub fn task_from_waker(waker: &Waker) -> TaskRef {
36 // safety: OK because WakerHack has the same layout as Waker. 37 // safety: OK because WakerHack has the same layout as Waker.
37 // This is not really guaranteed because the structs are `repr(Rust)`, it is 38 // This is not really guaranteed because the structs are `repr(Rust)`, it is
@@ -46,7 +47,31 @@ pub fn task_from_waker(waker: &Waker) -> TaskRef {
46 unsafe { TaskRef::from_ptr(hack.data as *const TaskHeader) } 47 unsafe { TaskRef::from_ptr(hack.data as *const TaskHeader) }
47} 48}
48 49
50#[cfg(not(feature = "nightly"))]
49struct WakerHack { 51struct WakerHack {
50 data: *const (), 52 data: *const (),
51 vtable: &'static RawWakerVTable, 53 vtable: &'static RawWakerVTable,
52} 54}
55
56/// Get a task pointer from a waker.
57///
58/// This can be used as an optimization in wait queues to store task pointers
59/// (1 word) instead of full Wakers (2 words). This saves a bit of RAM and helps
60/// avoid dynamic dispatch.
61///
62/// You can use the returned task pointer to wake the task with [`wake_task`](super::wake_task).
63///
64/// # Panics
65///
66/// Panics if the waker is not created by the Embassy executor.
67#[cfg(feature = "nightly")]
68pub fn task_from_waker(waker: &Waker) -> TaskRef {
69 let raw_waker = waker.as_raw();
70
71 if raw_waker.vtable() != &VTABLE {
72 panic!("Found waker not created by the Embassy executor. `embassy_time::Timer` only works with the Embassy executor.")
73 }
74
75 // safety: our wakers are always created with `TaskRef::as_ptr`
76 unsafe { TaskRef::from_ptr(raw_waker.data() as *const TaskHeader) }
77}