Skip to content

Commit d4ea007

Browse files
authored
Try to be more helpful with the executor (#4313)
1 parent 67e8a83 commit d4ea007

File tree

4 files changed

+30
-8
lines changed

4 files changed

+30
-8
lines changed

esp-rtos/src/embassy/mod.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use core::{cell::UnsafeCell, mem::MaybeUninit, sync::atomic::Ordering};
44

55
use embassy_executor::{SendSpawner, Spawner, raw};
66
use esp_hal::interrupt::{InterruptHandler, Priority, software::SoftwareInterrupt};
7+
#[cfg(multi_core)]
8+
use esp_hal::system::Cpu;
79
use macros::ram;
810
use portable_atomic::AtomicPtr;
911

@@ -40,7 +42,16 @@ pub trait Callbacks {
4042

4143
/// Thread-mode executor.
4244
///
43-
/// This executor runs in an OS thread.
45+
/// This executor runs in an OS thread, meaning the scheduler needs to be started before using any
46+
/// async operations.
47+
#[cfg_attr(
48+
multi_core,
49+
doc = r"
50+
51+
If you want to start the executor on the second core, you will need to start the second core using [`crate::start_second_core`].
52+
If you are looking for a way to run code on the second core without the scheduler, use the [`InterruptExecutor`].
53+
"
54+
)]
4455
pub struct Executor {
4556
executor: UnsafeCell<MaybeUninit<raw::Executor>>,
4657
}
@@ -129,6 +140,14 @@ impl Executor {
129140
))
130141
};
131142

143+
#[cfg(multi_core)]
144+
if Cpu::current() != Cpu::ProCpu
145+
&& crate::SCHEDULER
146+
.with(|scheduler| !scheduler.per_cpu[Cpu::current() as usize].initialized)
147+
{
148+
panic!("Executor cannot be started: the scheduler is not running on the current CPU.");
149+
}
150+
132151
init(executor.spawner());
133152

134153
loop {

esp-rtos/src/scheduler.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ impl SchedulerState {
117117
}
118118
}
119119

120+
pub(crate) fn current_task(&self, cpu: Cpu) -> TaskPtr {
121+
unwrap!(
122+
self.per_cpu[cpu as usize].current_task,
123+
"The scheduler is not running on the current CPU. Make sure you start the scheduler before calling OS functions."
124+
)
125+
}
126+
120127
pub(crate) fn setup(&mut self, time_driver: TimeDriver, idle_hook: IdleFn) {
121128
assert!(
122129
self.time_driver.is_none(),
@@ -437,8 +444,7 @@ impl Scheduler {
437444

438445
pub(crate) fn sleep_until(&self, wake_at: Instant) -> bool {
439446
self.with(|scheduler| {
440-
let current_cpu = Cpu::current() as usize;
441-
let current_task = unwrap!(scheduler.per_cpu[current_cpu].current_task);
447+
let current_task = scheduler.current_task(Cpu::current());
442448
if scheduler.sleep_task_until(current_task, wake_at) {
443449
task::yield_task();
444450
true

esp-rtos/src/semaphore.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ impl SemaphoreInner {
4646
..
4747
} => {
4848
SCHEDULER.with(|scheduler| {
49-
let current_cpu = Cpu::current() as usize;
50-
let current = unwrap!(scheduler.per_cpu[current_cpu].current_task);
49+
let current = scheduler.current_task(Cpu::current());
5150
if let Some(owner) = owner {
5251
if *owner == current && *recursive {
5352
*lock_counter += 1;

esp-rtos/src/wait_queue.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ impl WaitQueue {
3232

3333
pub(crate) fn wait_with_deadline(&mut self, deadline: Instant) {
3434
SCHEDULER.with(|scheduler| {
35-
let current_cpu = Cpu::current() as usize;
36-
let mut task = unwrap!(scheduler.per_cpu[current_cpu].current_task);
37-
35+
let mut task = scheduler.current_task(Cpu::current());
3836
if scheduler.sleep_task_until(task, deadline) {
3937
self.waiting_tasks.push(task);
4038
unsafe {

0 commit comments

Comments
 (0)