Skip to content

Commit

Permalink
Rewrite time driver (#2559)
Browse files Browse the repository at this point in the history
* Rewrite time driver

* Don't store priority

* Changelog

* Fix doc example

* Use separate locks for Alarms

* Mention generic queues

* Cache the next wakeup timestamp

* Immediately repoll if timestamp is in the past

* Add benchmark

* Remove equality check for now

* Enable interrupts when allocating the alarm

* Clean up

* Use relaxed ordering

* wut

* Typo

* Move benchmar

* fmt
  • Loading branch information
bugadani authored Nov 25, 2024
1 parent b06c7a4 commit aed0fac
Show file tree
Hide file tree
Showing 8 changed files with 264 additions and 122 deletions.
1 change: 1 addition & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[alias]
xtask = "run --package xtask --"
xfmt = "xtask fmt-packages"
qa = "xtask run-example qa-test"
1 change: 1 addition & 0 deletions esp-hal-embassy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Reduce memory footprint by 4 bytes on multi-core MCUs.
- The time driver no longer uses cross-core critical sections. (#2559)

### Fixed

Expand Down
11 changes: 6 additions & 5 deletions esp-hal-embassy/src/executor/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub(crate) fn pend_thread_mode(_core: usize) {
#[cfg(low_power_wait)]
{
// Signal that there is work to be done.
SIGNAL_WORK_THREAD_MODE[_core].store(true, Ordering::SeqCst);
SIGNAL_WORK_THREAD_MODE[_core].store(true, Ordering::Relaxed);

// If we are pending a task on the current core, we're done. Otherwise, we
// need to make sure the other core wakes up.
Expand Down Expand Up @@ -123,7 +123,8 @@ This will use software-interrupt 3 which isn't available for anything else to wa

// we do not care about race conditions between the load and store operations,
// interrupts will only set this value to true.
if SIGNAL_WORK_THREAD_MODE[cpu].load(Ordering::SeqCst) {
// Acquire makes no sense but at this time it's slightly faster than Relaxed.
if SIGNAL_WORK_THREAD_MODE[cpu].load(Ordering::Acquire) {
// if there is work to do, exit critical section and loop back to polling
unsafe {
core::arch::asm!(
Expand All @@ -140,7 +141,7 @@ This will use software-interrupt 3 which isn't available for anything else to wa
unsafe { core::arch::asm!("waiti 0") };
}
// If this races and some waker sets the signal, we'll reset it, but still poll.
SIGNAL_WORK_THREAD_MODE[cpu].store(false, Ordering::SeqCst);
SIGNAL_WORK_THREAD_MODE[cpu].store(false, Ordering::Relaxed);
}

#[cfg(all(riscv, low_power_wait))]
Expand All @@ -149,14 +150,14 @@ This will use software-interrupt 3 which isn't available for anything else to wa
// interrupts will only set this value to true.
critical_section::with(|_| {
// if there is work to do, loop back to polling
if !SIGNAL_WORK_THREAD_MODE[cpu].load(Ordering::SeqCst) {
if !SIGNAL_WORK_THREAD_MODE[cpu].load(Ordering::Relaxed) {
// if not, wait for interrupt
unsafe { core::arch::asm!("wfi") };
}
});
// if an interrupt occurred while waiting, it will be serviced here
// If this races and some waker sets the signal, we'll reset it, but still poll.
SIGNAL_WORK_THREAD_MODE[cpu].store(false, Ordering::SeqCst);
SIGNAL_WORK_THREAD_MODE[cpu].store(false, Ordering::Relaxed);
}
}

Expand Down
2 changes: 1 addition & 1 deletion esp-hal-embassy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl_array!(4);
///
/// ```rust, no_run
#[doc = esp_hal::before_snippet!()]
/// use esp_hal::timg::TimerGroup;
/// use esp_hal::timer::timg::TimerGroup;
///
/// let timg0 = TimerGroup::new(peripherals.TIMG0);
/// esp_hal_embassy::init(timg0.timer0);
Expand Down
Loading

0 comments on commit aed0fac

Please sign in to comment.