58 lines
1.9 KiB
Rust
Raw Normal View History

#[cfg(feature = "executor-interrupt")]
compile_error!("`executor-interrupt` is not supported with `arch-riscv32`.");
#[cfg(feature = "executor-thread")]
pub use thread::*;
#[cfg(feature = "executor-thread")]
mod thread {
use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(feature = "nightly")]
pub use embassy_macros::main_riscv as main;
2023-08-14 08:57:14 +02:00
use crate::raw::PenderContext;
2023-08-12 16:00:18 +02:00
use crate::thread::ThreadContext;
/// global atomic used to keep track of whether there is work to do since sev() is not available on RISCV
static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false);
2023-08-14 08:57:14 +02:00
#[export_name = "__pender"]
fn __thread_mode_pender(_context: PenderContext) {
2023-08-12 16:00:18 +02:00
SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst);
}
2023-08-12 16:00:18 +02:00
/// TODO
// Name pending
#[derive(Default)] // Default enables Executor::new
2023-08-12 22:42:50 +02:00
pub struct Context;
2023-08-12 22:42:50 +02:00
impl ThreadContext for Context {
2023-08-14 08:57:14 +02:00
fn context(&self) -> PenderContext {
2023-08-14 15:16:40 +02:00
unsafe { core::mem::transmute(0) }
}
2023-08-12 16:00:18 +02:00
fn wait(&mut self) {
// We do not care about race conditions between the load and store operations,
// interrupts will only set this value to true.
critical_section::with(|_| {
// if there is work to do, loop back to polling
// TODO can we relax this?
if SIGNAL_WORK_THREAD_MODE.load(Ordering::SeqCst) {
SIGNAL_WORK_THREAD_MODE.store(false, Ordering::SeqCst);
}
2023-08-12 16:00:18 +02:00
// if not, wait for interrupt
else {
unsafe {
core::arch::asm!("wfi");
}
}
});
// if an interrupt occurred while waiting, it will be serviced here
}
}
2023-08-12 16:00:18 +02:00
/// TODO
// Type alias for backwards compatibility
2023-08-12 22:42:50 +02:00
pub type Executor = crate::thread::ThreadModeExecutor<Context>;
}