80 lines
2 KiB
Rust
80 lines
2 KiB
Rust
#[cfg(feature = "executor-interrupt")]
|
|
compile_error!("`executor-interrupt` is not supported with `arch-std`.");
|
|
|
|
#[cfg(not(feature = "thread-context"))]
|
|
compile_error!("`arch-std` requires `thread-context`.");
|
|
|
|
#[cfg(feature = "executor-thread")]
|
|
pub use thread::*;
|
|
#[cfg(feature = "executor-thread")]
|
|
mod thread {
|
|
use std::sync::{Condvar, Mutex};
|
|
|
|
#[cfg(feature = "nightly")]
|
|
pub use embassy_macros::main_std as main;
|
|
|
|
use crate::raw::OpaqueThreadContext;
|
|
use crate::thread::ThreadContext;
|
|
|
|
/// TODO
|
|
// Name pending
|
|
pub struct StdThreadCtx {
|
|
signaler: &'static Signaler,
|
|
}
|
|
|
|
impl Default for StdThreadCtx {
|
|
fn default() -> Self {
|
|
Self {
|
|
signaler: &*Box::leak(Box::new(Signaler::new())),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl ThreadContext for StdThreadCtx {
|
|
fn context(&self) -> OpaqueThreadContext {
|
|
OpaqueThreadContext(self.signaler as *const _ as usize)
|
|
}
|
|
|
|
fn wait(&mut self) {
|
|
self.signaler.wait()
|
|
}
|
|
}
|
|
|
|
#[export_name = "__thread_mode_pender"]
|
|
fn __thread_mode_pender(core_id: OpaqueThreadContext) {
|
|
let signaler: &'static Signaler = unsafe { std::mem::transmute(core_id) };
|
|
signaler.signal()
|
|
}
|
|
|
|
struct Signaler {
|
|
mutex: Mutex<bool>,
|
|
condvar: Condvar,
|
|
}
|
|
|
|
impl Signaler {
|
|
fn new() -> Self {
|
|
Self {
|
|
mutex: Mutex::new(false),
|
|
condvar: Condvar::new(),
|
|
}
|
|
}
|
|
|
|
fn wait(&self) {
|
|
let mut signaled = self.mutex.lock().unwrap();
|
|
while !*signaled {
|
|
signaled = self.condvar.wait(signaled).unwrap();
|
|
}
|
|
*signaled = false;
|
|
}
|
|
|
|
fn signal(&self) {
|
|
let mut signaled = self.mutex.lock().unwrap();
|
|
*signaled = true;
|
|
self.condvar.notify_one();
|
|
}
|
|
}
|
|
|
|
/// TODO
|
|
// Type alias for backwards compatibility
|
|
pub type Executor = crate::thread::ThreadModeExecutor<StdThreadCtx>;
|
|
}
|