Skip to content

Commit c0eb645

Browse files
committed
Remove portable-atomic from rtic-monotonics
1 parent 1b49d0d commit c0eb645

File tree

9 files changed

+130
-30
lines changed

9 files changed

+130
-30
lines changed

rtic-monotonics/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ For each category, *Added*, *Changed*, *Fixed* add new entries at the top!
88
## Unreleased
99

1010
### Changed
11+
1112
- Panic if STM32 prescaler value would overflow
13+
- Moved away from `portable-atomic` due to it's spinlock design
1214

1315
### Added
1416

rtic-monotonics/Cargo.toml

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,9 @@ rustdoc-flags = ["--cfg", "docsrs"]
3939
[dependencies]
4040
rtic-time = { version = "2.0.0", path = "../rtic-time" }
4141
fugit = { version = "0.3.6" }
42-
portable-atomic = { version = "1" }
4342
cfg-if = "1.0.0"
4443
cortex-m = { version = "0.7.6", optional = true }
45-
critical-section = { version = "1", optional = true }
44+
critical-section = { version = "1" }
4645

4746
# RP2040
4847
rp2040-pac = { version = "0.6", optional = true }
@@ -94,15 +93,15 @@ rp2040 = ["dep:cortex-m", "dep:rp2040-pac"]
9493
rp235x = ["dep:cortex-m", "dep:rp235x-pac"]
9594

9695
# nRF Timers and RTC
97-
nrf52805 = ["dep:cortex-m", "dep:nrf52805-pac", "dep:critical-section"]
98-
nrf52810 = ["dep:cortex-m", "dep:nrf52810-pac", "dep:critical-section"]
99-
nrf52811 = ["dep:cortex-m", "dep:nrf52811-pac", "dep:critical-section"]
100-
nrf52832 = ["dep:cortex-m", "dep:nrf52832-pac", "dep:critical-section"]
101-
nrf52833 = ["dep:cortex-m", "dep:nrf52833-pac", "dep:critical-section"]
102-
nrf52840 = ["dep:cortex-m", "dep:nrf52840-pac", "dep:critical-section"]
103-
nrf5340-app = ["dep:cortex-m", "dep:nrf5340-app-pac", "dep:critical-section"]
104-
nrf5340-net = ["dep:cortex-m", "dep:nrf5340-net-pac", "dep:critical-section"]
105-
nrf9160 = ["dep:cortex-m", "dep:nrf9160-pac", "dep:critical-section"]
96+
nrf52805 = ["dep:cortex-m", "dep:nrf52805-pac"]
97+
nrf52810 = ["dep:cortex-m", "dep:nrf52810-pac"]
98+
nrf52811 = ["dep:cortex-m", "dep:nrf52811-pac"]
99+
nrf52832 = ["dep:cortex-m", "dep:nrf52832-pac"]
100+
nrf52833 = ["dep:cortex-m", "dep:nrf52833-pac"]
101+
nrf52840 = ["dep:cortex-m", "dep:nrf52840-pac"]
102+
nrf5340-app = ["dep:cortex-m", "dep:nrf5340-app-pac"]
103+
nrf5340-net = ["dep:cortex-m", "dep:nrf5340-net-pac"]
104+
nrf9160 = ["dep:cortex-m", "dep:nrf9160-pac"]
106105

107106
# i.MX RT Timers
108107
# Use as `features = ["imxrt_gpt1"]`

rtic-monotonics/src/imxrt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
//! }
3131
//! ```
3232
33-
use portable_atomic::{AtomicU32, Ordering};
33+
use crate::atomic::{AtomicU32, Ordering};
3434
use rtic_time::{
3535
half_period_counter::calculate_now,
3636
timer_queue::{TimerQueue, TimerQueueBackend},

rtic-monotonics/src/lib.rs

Lines changed: 110 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
//! In-tree implementations of the [`rtic_time::Monotonic`] (reexported) trait for
22
//! timers & clocks found on commonly used microcontrollers.
33
//!
4-
//! If you are using a microcontroller where CAS operations are not available natively, you might
5-
//! have to enable the `critical-section` or `unsafe-assume-single-core` feature of the
6-
//! [`portable-atomic`](https://docs.rs/portable-atomic/latest/portable_atomic/) dependency
7-
//! yourself for this dependency to compile.
8-
//!
94
//! To enable the implementations, you must enable a feature for the specific MCU you're targeting.
105
//!
116
//! # Cortex-M Systick
@@ -135,3 +130,113 @@ pub(crate) unsafe fn set_monotonic_prio(
135130

136131
nvic.set_priority(interrupt, hw_prio);
137132
}
133+
134+
mod atomic {
135+
//! Use a critical section for atomics in case the HW does not support atomics of specific
136+
//! sizes.
137+
138+
#![allow(unused)]
139+
140+
pub use core::sync::atomic::Ordering;
141+
142+
#[cfg(target_has_atomic = "32")]
143+
pub use core::sync::atomic::AtomicU32;
144+
#[cfg(not(target_has_atomic = "32"))]
145+
pub struct AtomicU32(core::cell::UnsafeCell<u32>);
146+
147+
#[cfg(not(target_has_atomic = "32"))]
148+
impl AtomicU32 {
149+
/// Create a new atomic.
150+
#[inline]
151+
pub const fn new(val: u32) -> Self {
152+
Self(core::cell::UnsafeCell::new(val))
153+
}
154+
155+
/// Store the value.
156+
#[inline]
157+
pub fn store(&self, val: u32, _ordering: Ordering) {
158+
critical_section::with(|_| unsafe {
159+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
160+
self.0.get().write(val);
161+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
162+
});
163+
}
164+
165+
/// Read the value.
166+
#[inline]
167+
pub fn load(&self, _ordering: Ordering) -> u32 {
168+
critical_section::with(|_| unsafe {
169+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
170+
let r = self.0.get().read();
171+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
172+
r
173+
})
174+
}
175+
176+
/// Read the value.
177+
#[inline]
178+
pub fn fetch_add(&self, val: u32, _ordering: Ordering) -> u32 {
179+
critical_section::with(|_| {
180+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
181+
let curr = unsafe { self.0.get().read() };
182+
unsafe { self.0.get().write(curr.wrapping_add(val)) };
183+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
184+
curr
185+
})
186+
}
187+
}
188+
189+
#[cfg(not(target_has_atomic = "32"))]
190+
unsafe impl Sync for AtomicU32 {}
191+
192+
#[cfg(target_has_atomic = "64")]
193+
pub use core::sync::atomic::AtomicU64;
194+
195+
#[cfg(not(target_has_atomic = "64"))]
196+
pub struct AtomicU64(core::cell::UnsafeCell<u64>);
197+
198+
#[cfg(not(target_has_atomic = "64"))]
199+
impl AtomicU64 {
200+
/// Create a new atomic.
201+
#[inline]
202+
pub const fn new(val: u64) -> Self {
203+
Self(core::cell::UnsafeCell::new(val))
204+
}
205+
206+
/// Store the value.
207+
#[inline]
208+
pub fn store(&self, val: u64, _ordering: Ordering) {
209+
critical_section::with(|_| unsafe {
210+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
211+
self.0.get().write(val);
212+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
213+
});
214+
}
215+
216+
/// Read the value.
217+
#[inline]
218+
pub fn load(&self, _ordering: Ordering) -> u64 {
219+
critical_section::with(|_| unsafe {
220+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
221+
let r = self.0.get().read();
222+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
223+
r
224+
})
225+
}
226+
227+
/// Read the value.
228+
#[inline]
229+
pub fn fetch_add(&self, val: u64, _ordering: Ordering) -> u64 {
230+
critical_section::with(|_| {
231+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
232+
let curr = unsafe { self.0.get().read() };
233+
unsafe { self.0.get().write(curr.wrapping_add(val)) };
234+
core::sync::atomic::compiler_fence(Ordering::SeqCst);
235+
curr
236+
})
237+
}
238+
}
239+
240+
#[cfg(not(target_has_atomic = "64"))]
241+
unsafe impl Sync for AtomicU64 {}
242+
}

rtic-monotonics/src/nrf/rtc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub use nrf5340_net_pac::{self as pac, RTC0_NS as RTC0, RTC1_NS as RTC1};
6666
#[doc(hidden)]
6767
pub use nrf9160_pac::{self as pac, RTC0_NS as RTC0, RTC1_NS as RTC1};
6868

69-
use portable_atomic::{AtomicU32, Ordering};
69+
use crate::atomic::{AtomicU32, Ordering};
7070
use rtic_time::{
7171
half_period_counter::calculate_now,
7272
timer_queue::{TimerQueue, TimerQueueBackend},

rtic-monotonics/src/nrf/timer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub use nrf5340_net_pac::{
7676
#[doc(hidden)]
7777
pub use nrf9160_pac::{self as pac, TIMER0_NS as TIMER0, TIMER1_NS as TIMER1, TIMER2_NS as TIMER2};
7878

79-
use portable_atomic::{AtomicU32, Ordering};
79+
use crate::atomic::{AtomicU32, Ordering};
8080
use rtic_time::{
8181
half_period_counter::calculate_now,
8282
timer_queue::{TimerQueue, TimerQueueBackend},

rtic-monotonics/src/stm32.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub mod prelude {
5656
pub use fugit::{self, ExtU64, ExtU64Ceil};
5757
}
5858

59-
use portable_atomic::{AtomicU64, Ordering};
59+
use crate::atomic::{AtomicU64, Ordering};
6060
use rtic_time::{
6161
half_period_counter::calculate_now,
6262
timer_queue::{TimerQueue, TimerQueueBackend},

rtic-monotonics/src/systick.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,17 @@ pub mod prelude {
6666

6767
pub use cortex_m::peripheral::{syst::SystClkSource, SYST};
6868

69-
use portable_atomic::Ordering;
69+
use crate::atomic::Ordering;
7070
use rtic_time::timer_queue::TimerQueue;
7171

7272
use crate::TimerQueueBackend;
7373

7474
cfg_if::cfg_if! {
7575
if #[cfg(feature = "systick-64bit")] {
76-
use portable_atomic::AtomicU64;
76+
use crate::atomic::AtomicU64;
7777
static SYSTICK_CNT: AtomicU64 = AtomicU64::new(0);
7878
} else {
79-
use portable_atomic::AtomicU32;
79+
use crate::atomic::AtomicU32;
8080
static SYSTICK_CNT: AtomicU32 = AtomicU32::new(0);
8181
}
8282
}

xtask/src/argument_parsing.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,7 @@ impl Package {
6868
if let Some(features) = features {
6969
features
7070
.iter()
71-
.map(|&s| {
72-
if matches!(backend, Backends::Thumbv6) {
73-
format!("{s},portable-atomic/critical-section")
74-
} else {
75-
s.to_string()
76-
}
77-
})
71+
.map(|&s| s.to_string())
7872
.map(Some)
7973
.chain(std::iter::once(None))
8074
.collect()

0 commit comments

Comments
 (0)