diff options
Diffstat (limited to 'embassy-executor/src')
| -rw-r--r-- | embassy-executor/src/raw/mod.rs | 1 | ||||
| -rw-r--r-- | embassy-executor/src/raw/waker_turbo.rs | 34 |
2 files changed, 35 insertions, 0 deletions
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 15ff18fc8..72c367c33 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -11,6 +11,7 @@ mod run_queue; | |||
| 11 | #[cfg(feature = "integrated-timers")] | 11 | #[cfg(feature = "integrated-timers")] |
| 12 | mod timer_queue; | 12 | mod timer_queue; |
| 13 | pub(crate) mod util; | 13 | pub(crate) mod util; |
| 14 | #[cfg_attr(feature = "turbowakers", path = "waker_turbo.rs")] | ||
| 14 | mod waker; | 15 | mod waker; |
| 15 | 16 | ||
| 16 | use core::future::Future; | 17 | use core::future::Future; |
diff --git a/embassy-executor/src/raw/waker_turbo.rs b/embassy-executor/src/raw/waker_turbo.rs new file mode 100644 index 000000000..435a0ff7e --- /dev/null +++ b/embassy-executor/src/raw/waker_turbo.rs | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | use core::ptr::NonNull; | ||
| 2 | use core::task::Waker; | ||
| 3 | |||
| 4 | use super::{wake_task, TaskHeader, TaskRef}; | ||
| 5 | |||
| 6 | pub(crate) unsafe fn from_task(p: TaskRef) -> Waker { | ||
| 7 | Waker::from_turbo_ptr(NonNull::new_unchecked(p.as_ptr() as _)) | ||
| 8 | } | ||
| 9 | |||
| 10 | /// Get a task pointer from a waker. | ||
| 11 | /// | ||
| 12 | /// This can be used as an optimization in wait queues to store task pointers | ||
| 13 | /// (1 word) instead of full Wakers (2 words). This saves a bit of RAM and helps | ||
| 14 | /// avoid dynamic dispatch. | ||
| 15 | /// | ||
| 16 | /// You can use the returned task pointer to wake the task with [`wake_task`](super::wake_task). | ||
| 17 | /// | ||
| 18 | /// # Panics | ||
| 19 | /// | ||
| 20 | /// Panics if the waker is not created by the Embassy executor. | ||
| 21 | pub fn task_from_waker(waker: &Waker) -> TaskRef { | ||
| 22 | let ptr = waker.as_turbo_ptr().as_ptr(); | ||
| 23 | |||
| 24 | // safety: our wakers are always created with `TaskRef::as_ptr` | ||
| 25 | unsafe { TaskRef::from_ptr(ptr as *const TaskHeader) } | ||
| 26 | } | ||
| 27 | |||
| 28 | #[inline(never)] | ||
| 29 | #[no_mangle] | ||
| 30 | fn _turbo_wake(ptr: NonNull<()>) { | ||
| 31 | // safety: our wakers are always created with `TaskRef::as_ptr` | ||
| 32 | let task = unsafe { TaskRef::from_ptr(ptr.as_ptr() as *const TaskHeader) }; | ||
| 33 | wake_task(task) | ||
| 34 | } | ||
