diff options
Diffstat (limited to 'embassy-executor/src')
| -rw-r--r-- | embassy-executor/src/lib.rs | 1 | ||||
| -rw-r--r-- | embassy-executor/src/raw/waker.rs | 25 |
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"))] | ||
| 35 | pub fn task_from_waker(waker: &Waker) -> TaskRef { | 36 | pub 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"))] | ||
| 49 | struct WakerHack { | 51 | struct 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")] | ||
| 68 | pub 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 | } | ||
