Add initialize

This commit is contained in:
Dániel Buga 2024-11-19 15:59:31 +01:00
parent ff02ee1a22
commit 8ebe059ecb
No known key found for this signature in database
10 changed files with 56 additions and 9 deletions

View File

@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## Unreleased
- Only set integrated-timers callbacks once per executor. - `raw::Executor` now has an `fn initialize` that must be called once before starting to poll it.
## 0.6.3 - 2024-11-12 ## 0.6.3 - 2024-11-12

View File

@ -53,6 +53,10 @@ mod thread {
/// ///
/// This function never returns. /// This function never returns.
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
unsafe {
self.inner.initialize();
}
init(self.inner.spawner()); init(self.inner.spawner());
loop { loop {

View File

@ -98,6 +98,9 @@ mod thread {
/// ///
/// This function never returns. /// This function never returns.
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
unsafe {
self.inner.initialize();
}
init(self.inner.spawner()); init(self.inner.spawner());
loop { loop {
@ -207,6 +210,9 @@ mod interrupt {
} }
let executor = unsafe { (&*self.executor.get()).assume_init_ref() }; let executor = unsafe { (&*self.executor.get()).assume_init_ref() };
unsafe {
executor.initialize();
}
unsafe { NVIC::unmask(irq) } unsafe { NVIC::unmask(irq) }

View File

@ -54,6 +54,10 @@ mod thread {
/// ///
/// This function never returns. /// This function never returns.
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
unsafe {
self.inner.initialize();
}
init(self.inner.spawner()); init(self.inner.spawner());
loop { loop {

View File

@ -48,6 +48,10 @@ mod thread {
/// ///
/// This function never returns. /// This function never returns.
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
unsafe {
self.inner.initialize();
}
init(self.inner.spawner()); init(self.inner.spawner());
loop { loop {

View File

@ -55,6 +55,10 @@ mod thread {
/// ///
/// This function never returns. /// This function never returns.
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
unsafe {
self.inner.initialize();
}
init(self.inner.spawner()); init(self.inner.spawner());
loop { loop {

View File

@ -70,6 +70,10 @@ mod thread {
/// - a `static mut` (unsafe) /// - a `static mut` (unsafe)
/// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
pub fn start(&'static mut self, init: impl FnOnce(Spawner)) { pub fn start(&'static mut self, init: impl FnOnce(Spawner)) {
unsafe {
self.inner.initialize();
}
unsafe { unsafe {
let executor = &self.inner; let executor = &self.inner;
let future = Closure::new(move |_| { let future = Closure::new(move |_| {

View File

@ -328,7 +328,7 @@ impl SyncExecutor {
#[cfg(feature = "integrated-timers")] #[cfg(feature = "integrated-timers")]
let alarm = unsafe { unwrap!(embassy_time_driver::allocate_alarm()) }; let alarm = unsafe { unwrap!(embassy_time_driver::allocate_alarm()) };
let this = Self { Self {
run_queue: RunQueue::new(), run_queue: RunQueue::new(),
pender, pender,
@ -336,12 +336,12 @@ impl SyncExecutor {
timer_queue: timer_queue::TimerQueue::new(), timer_queue: timer_queue::TimerQueue::new(),
#[cfg(feature = "integrated-timers")] #[cfg(feature = "integrated-timers")]
alarm, alarm,
}; }
}
pub(crate) unsafe fn initialize(&'static self) {
#[cfg(feature = "integrated-timers")] #[cfg(feature = "integrated-timers")]
embassy_time_driver::set_alarm_callback(this.alarm, Self::alarm_callback, &this as *const _ as *mut ()); embassy_time_driver::set_alarm_callback(self.alarm, Self::alarm_callback, self as *const _ as *mut ());
this
} }
/// Enqueue a task in the task queue /// Enqueue a task in the task queue
@ -494,6 +494,15 @@ impl Executor {
} }
} }
/// Initializes the executor.
///
/// # Safety
///
/// This function must be called once before any other method is called.
pub unsafe fn initialize(&'static self) {
self.inner.initialize();
}
/// Spawn a task in this executor. /// Spawn a task in this executor.
/// ///
/// # Safety /// # Safety
@ -518,6 +527,8 @@ impl Executor {
/// ///
/// # Safety /// # Safety
/// ///
/// You must call `initialize` before calling this method.
///
/// You must NOT call `poll` reentrantly on the same executor. /// You must NOT call `poll` reentrantly on the same executor.
/// ///
/// In particular, note that `poll` may call the pender synchronously. Therefore, you /// In particular, note that `poll` may call the pender synchronously. Therefore, you

View File

@ -40,6 +40,10 @@ fn setup() -> (&'static Executor, Trace) {
let trace = Trace::new(); let trace = Trace::new();
let context = Box::leak(Box::new(trace.clone())) as *mut _ as *mut (); let context = Box::leak(Box::new(trace.clone())) as *mut _ as *mut ();
let executor = &*Box::leak(Box::new(Executor::new(context))); let executor = &*Box::leak(Box::new(Executor::new(context)));
unsafe {
executor.initialize();
}
(executor, trace) (executor, trace)
} }

View File

@ -155,7 +155,9 @@ impl Executor {
time_driver: get_driver(), time_driver: get_driver(),
}); });
EXECUTOR.as_mut().unwrap() let executor = EXECUTOR.as_mut().unwrap();
executor
}) })
} }
@ -241,11 +243,15 @@ impl Executor {
/// ///
/// This function never returns. /// This function never returns.
pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
init(unsafe { EXECUTOR.as_mut().unwrap() }.inner.spawner()); let executor = unsafe { EXECUTOR.as_mut().unwrap() };
unsafe {
executor.inner.initialize();
}
init(executor.inner.spawner());
loop { loop {
unsafe { unsafe {
EXECUTOR.as_mut().unwrap().inner.poll(); executor.inner.poll();
self.configure_pwr(); self.configure_pwr();
asm!("wfe"); asm!("wfe");
}; };