Make PenderContext opaque

This commit is contained in:
Dániel Buga 2023-08-14 15:16:40 +02:00
parent f6007869bf
commit 4c4b12c307
6 changed files with 30 additions and 9 deletions

View file

@ -36,6 +36,7 @@ unsafe fn nvic_pend(irq: u16) {
#[export_name = "__pender"] #[export_name = "__pender"]
fn __pender(context: PenderContext) { fn __pender(context: PenderContext) {
unsafe { unsafe {
let context: usize = core::mem::transmute(context);
// Safety: `context` is either `usize::MAX` created by `Executor::run`, or a valid interrupt // Safety: `context` is either `usize::MAX` created by `Executor::run`, or a valid interrupt
// request number given to `InterruptExecutor::start`. // request number given to `InterruptExecutor::start`.
if context as usize == usize::MAX { if context as usize == usize::MAX {
@ -56,6 +57,7 @@ fn __pender(_context: PenderContext) {
#[export_name = "__pender"] #[export_name = "__pender"]
fn __pender(context: PenderContext) { fn __pender(context: PenderContext) {
unsafe { unsafe {
let context: usize = core::mem::transmute(context);
// Safety: `context` is the same value we passed to `InterruptExecutor::start`, which must // Safety: `context` is the same value we passed to `InterruptExecutor::start`, which must
// be a valid interrupt request number. // be a valid interrupt request number.
nvic_pend(context as u16) nvic_pend(context as u16)
@ -78,7 +80,7 @@ mod thread {
impl ThreadContext for Context { impl ThreadContext for Context {
fn context(&self) -> PenderContext { fn context(&self) -> PenderContext {
usize::MAX unsafe { core::mem::transmute(usize::MAX) }
} }
fn wait(&mut self) { fn wait(&mut self) {
@ -106,7 +108,7 @@ mod interrupt {
T: InterruptNumber, T: InterruptNumber,
{ {
fn context(&self) -> PenderContext { fn context(&self) -> PenderContext {
self.number() as usize unsafe { core::mem::transmute(self.number() as usize) }
} }
fn enable(&self) { fn enable(&self) {

View file

@ -28,7 +28,7 @@ mod thread {
impl ThreadContext for Context { impl ThreadContext for Context {
fn context(&self) -> PenderContext { fn context(&self) -> PenderContext {
0 unsafe { core::mem::transmute(0) }
} }
fn wait(&mut self) { fn wait(&mut self) {

View file

@ -29,7 +29,7 @@ mod thread {
impl ThreadContext for Context { impl ThreadContext for Context {
fn context(&self) -> PenderContext { fn context(&self) -> PenderContext {
self.signaler as *const _ as usize unsafe { core::mem::transmute(self.signaler) }
} }
fn wait(&mut self) { fn wait(&mut self) {

View file

@ -49,7 +49,7 @@ mod thread {
pub fn new() -> Self { pub fn new() -> Self {
let ctx = &*Box::leak(Box::new(WasmContext::new())); let ctx = &*Box::leak(Box::new(WasmContext::new()));
Self { Self {
inner: raw::Executor::new(ctx as *const _ as usize), inner: raw::Executor::new(unsafe { core::mem::transmute(ctx) }),
ctx, ctx,
not_send: PhantomData, not_send: PhantomData,
} }

View file

@ -26,7 +26,7 @@ mod thread {
impl ThreadContext for Context { impl ThreadContext for Context {
fn context(&self) -> PenderContext { fn context(&self) -> PenderContext {
0 unsafe { core::mem::transmute(0) }
} }
fn wait(&mut self) { fn wait(&mut self) {

View file

@ -292,10 +292,29 @@ impl<F: Future + 'static, const N: usize> TaskPool<F, N> {
} }
/// Context given to the thread-mode executor's pender. /// Context given to the thread-mode executor's pender.
pub type PenderContext = usize; #[repr(transparent)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub(crate) struct Pender(PenderContext); pub struct PenderContext(usize);
/// Platform/architecture-specific action executed when an executor has pending work.
///
/// When a task within an executor is woken, the `Pender` is called. This does a
/// platform/architecture-specific action to signal there is pending work in the executor.
/// When this happens, you must arrange for [`Executor::poll`] to be called.
///
/// You can think of it as a waker, but for the whole executor.
///
/// Platform/architecture implementations must provide a function that can be referred to as:
///
/// ```rust
/// use embassy_executor::raw::PenderContext;
///
/// extern "Rust" {
/// fn __pender(context: PenderContext);
/// }
/// ```
#[derive(Clone, Copy)]
pub struct Pender(PenderContext);
unsafe impl Send for Pender {} unsafe impl Send for Pender {}
unsafe impl Sync for Pender {} unsafe impl Sync for Pender {}