mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-26 20:00:27 +00:00
Merge pull request #4619 from bugadani/perf
[backport] Fix executor perf on ESP32 MCUs
This commit is contained in:
commit
89684d31ff
@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
<!-- next-header -->
|
<!-- next-header -->
|
||||||
## Unreleased - ReleaseDate
|
## Unreleased - ReleaseDate
|
||||||
|
|
||||||
|
- Fixed performance regression on some ESP32 MCUs.
|
||||||
|
|
||||||
## 0.9.0 - 2025-08-26
|
## 0.9.0 - 2025-08-26
|
||||||
|
|
||||||
- Added `extern "Rust" fn __embassy_time_queue_item_from_waker`
|
- Added `extern "Rust" fn __embassy_time_queue_item_from_waker`
|
||||||
|
@ -12,8 +12,14 @@
|
|||||||
mod run_queue;
|
mod run_queue;
|
||||||
|
|
||||||
#[cfg_attr(all(cortex_m, target_has_atomic = "32"), path = "state_atomics_arm.rs")]
|
#[cfg_attr(all(cortex_m, target_has_atomic = "32"), path = "state_atomics_arm.rs")]
|
||||||
#[cfg_attr(all(not(cortex_m), target_has_atomic = "8"), path = "state_atomics.rs")]
|
#[cfg_attr(
|
||||||
#[cfg_attr(not(target_has_atomic = "8"), path = "state_critical_section.rs")]
|
all(not(cortex_m), any(target_has_atomic = "8", target_has_atomic = "32")),
|
||||||
|
path = "state_atomics.rs"
|
||||||
|
)]
|
||||||
|
#[cfg_attr(
|
||||||
|
not(any(target_has_atomic = "8", target_has_atomic = "32")),
|
||||||
|
path = "state_critical_section.rs"
|
||||||
|
)]
|
||||||
mod state;
|
mod state;
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
|
@ -1,4 +1,15 @@
|
|||||||
use core::sync::atomic::{AtomicU8, Ordering};
|
// Prefer pointer-width atomic operations, as narrower ones may be slower.
|
||||||
|
#[cfg(all(target_pointer_width = "32", target_has_atomic = "32"))]
|
||||||
|
type AtomicState = core::sync::atomic::AtomicU32;
|
||||||
|
#[cfg(not(all(target_pointer_width = "32", target_has_atomic = "32")))]
|
||||||
|
type AtomicState = core::sync::atomic::AtomicU8;
|
||||||
|
|
||||||
|
#[cfg(all(target_pointer_width = "32", target_has_atomic = "32"))]
|
||||||
|
type StateBits = u32;
|
||||||
|
#[cfg(not(all(target_pointer_width = "32", target_has_atomic = "32")))]
|
||||||
|
type StateBits = u8;
|
||||||
|
|
||||||
|
use core::sync::atomic::Ordering;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub(crate) struct Token(());
|
pub(crate) struct Token(());
|
||||||
@ -11,18 +22,18 @@ pub(crate) fn locked<R>(f: impl FnOnce(Token) -> R) -> R {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Task is spawned (has a future)
|
/// Task is spawned (has a future)
|
||||||
pub(crate) const STATE_SPAWNED: u8 = 1 << 0;
|
pub(crate) const STATE_SPAWNED: StateBits = 1 << 0;
|
||||||
/// Task is in the executor run queue
|
/// Task is in the executor run queue
|
||||||
pub(crate) const STATE_RUN_QUEUED: u8 = 1 << 1;
|
pub(crate) const STATE_RUN_QUEUED: StateBits = 1 << 1;
|
||||||
|
|
||||||
pub(crate) struct State {
|
pub(crate) struct State {
|
||||||
state: AtomicU8,
|
state: AtomicState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub const fn new() -> State {
|
pub const fn new() -> State {
|
||||||
Self {
|
Self {
|
||||||
state: AtomicU8::new(0),
|
state: AtomicState::new(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,13 +3,18 @@ use core::cell::Cell;
|
|||||||
pub(crate) use critical_section::{with as locked, CriticalSection as Token};
|
pub(crate) use critical_section::{with as locked, CriticalSection as Token};
|
||||||
use critical_section::{CriticalSection, Mutex};
|
use critical_section::{CriticalSection, Mutex};
|
||||||
|
|
||||||
|
#[cfg(target_arch = "avr")]
|
||||||
|
type StateBits = u8;
|
||||||
|
#[cfg(not(target_arch = "avr"))]
|
||||||
|
type StateBits = usize;
|
||||||
|
|
||||||
/// Task is spawned (has a future)
|
/// Task is spawned (has a future)
|
||||||
pub(crate) const STATE_SPAWNED: u8 = 1 << 0;
|
pub(crate) const STATE_SPAWNED: StateBits = 1 << 0;
|
||||||
/// Task is in the executor run queue
|
/// Task is in the executor run queue
|
||||||
pub(crate) const STATE_RUN_QUEUED: u8 = 1 << 1;
|
pub(crate) const STATE_RUN_QUEUED: StateBits = 1 << 1;
|
||||||
|
|
||||||
pub(crate) struct State {
|
pub(crate) struct State {
|
||||||
state: Mutex<Cell<u8>>,
|
state: Mutex<Cell<StateBits>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
@ -19,11 +24,11 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update<R>(&self, f: impl FnOnce(&mut u8) -> R) -> R {
|
fn update<R>(&self, f: impl FnOnce(&mut StateBits) -> R) -> R {
|
||||||
critical_section::with(|cs| self.update_with_cs(cs, f))
|
critical_section::with(|cs| self.update_with_cs(cs, f))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_with_cs<R>(&self, cs: CriticalSection<'_>, f: impl FnOnce(&mut u8) -> R) -> R {
|
fn update_with_cs<R>(&self, cs: CriticalSection<'_>, f: impl FnOnce(&mut StateBits) -> R) -> R {
|
||||||
let s = self.state.borrow(cs);
|
let s = self.state.borrow(cs);
|
||||||
let mut val = s.get();
|
let mut val = s.get();
|
||||||
let r = f(&mut val);
|
let r = f(&mut val);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user