Skip to content

Commit 6b5ac37

Browse files
committed
Migrate to portable-atomic
1 parent 3dff810 commit 6b5ac37

File tree

6 files changed

+15
-126
lines changed

6 files changed

+15
-126
lines changed

.github/workflows/doctests.yml

+1-9
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,10 @@ name: Documentation Tests
99
jobs:
1010
build:
1111
runs-on: ubuntu-latest
12-
strategy:
13-
matrix:
14-
include:
15-
- features: cortex-m
16-
nodefault: "--no-default-features"
17-
- features: ""
18-
nodefault: ""
19-
2012
steps:
2113
- uses: actions/checkout@v4
2214
- uses: dtolnay/rust-toolchain@stable
2315
- uses: actions-rs/cargo@v1
2416
with:
2517
command: test
26-
args: ${{ matrix.nodefault }} --features=${{ matrix.features }} --manifest-path core/Cargo.toml
18+
args: --manifest-path core/Cargo.toml

.github/workflows/embedded-builds.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
include:
1515
- features: ""
1616
target: thumbv7em-none-eabihf
17-
- feature: cortex-m
17+
- feature: portable-atomic/critical-section
1818
target: thumbv6m-none-eabi
1919

2020
steps:

core/Cargo.toml

+2-5
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,8 @@ categories = [
1515
license = "MIT OR Apache-2.0"
1616

1717
[dependencies]
18-
cortex-m = { version = "0.6.0", optional = true }
19-
20-
[dependencies.defmt]
21-
version = "0.3.0"
22-
optional = true
18+
portable-atomic = { version = "1.5.1", default-features = false, features = ["require-cas"] }
19+
defmt = { version = "0.3.0", optional = true }
2320

2421
[package.metadata.docs.rs]
2522
all-features = true

core/src/bbbuffer.rs

+11-99
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,10 @@ use core::{
1111
ptr::NonNull,
1212
result::Result as CoreResult,
1313
slice::from_raw_parts_mut,
14-
sync::atomic::{
15-
AtomicBool, AtomicUsize,
16-
Ordering::{AcqRel, Acquire, Release},
17-
},
14+
sync::atomic::Ordering::{AcqRel, Acquire, Release},
1815
};
16+
use portable_atomic::{AtomicBool, AtomicUsize};
17+
1918
#[derive(Debug)]
2019
/// A backing structure for a BBQueue. Can be used to create either
2120
/// a BBQueue or a split Producer/Consumer pair
@@ -63,9 +62,6 @@ impl<'a, const N: usize> BBBuffer<N> {
6362
/// is placed at `static` scope within the `.bss` region, the explicit initialization
6463
/// will be elided (as it is already performed as part of memory initialization)
6564
///
66-
/// NOTE: If the `cortex-m` feature is selected, this function takes a short critical section
67-
/// while splitting.
68-
///
6965
/// ```rust
7066
/// # // bbqueue test shim!
7167
/// # fn bbqtest() {
@@ -81,12 +77,11 @@ impl<'a, const N: usize> BBBuffer<N> {
8177
/// # }
8278
/// #
8379
/// # fn main() {
84-
/// # #[cfg(not(feature = "cortex-m"))]
8580
/// # bbqtest();
8681
/// # }
8782
/// ```
8883
pub fn try_split(&'a self) -> Result<(Producer<'a, N>, Consumer<'a, N>)> {
89-
if atomic::swap(&self.already_split, true, AcqRel) {
84+
if self.already_split.swap(true, AcqRel) {
9085
return Err(Error::AlreadySplit);
9186
}
9287

@@ -122,9 +117,6 @@ impl<'a, const N: usize> BBBuffer<N> {
122117
/// of the buffer. This is necessary to prevent undefined behavior. If the buffer
123118
/// is placed at `static` scope within the `.bss` region, the explicit initialization
124119
/// will be elided (as it is already performed as part of memory initialization)
125-
///
126-
/// NOTE: If the `cortex-m` feature is selected, this function takes a short critical
127-
/// section while splitting.
128120
pub fn try_split_framed(&'a self) -> Result<(FrameProducer<'a, N>, FrameConsumer<'a, N>)> {
129121
let (producer, consumer) = self.try_split()?;
130122
Ok((FrameProducer { producer }, FrameConsumer { consumer }))
@@ -159,7 +151,6 @@ impl<'a, const N: usize> BBBuffer<N> {
159151
/// # }
160152
/// #
161153
/// # fn main() {
162-
/// # #[cfg(not(feature = "cortex-m"))]
163154
/// # bbqtest();
164155
/// # }
165156
/// ```
@@ -345,14 +336,13 @@ impl<'a, const N: usize> Producer<'a, N> {
345336
/// # }
346337
/// #
347338
/// # fn main() {
348-
/// # #[cfg(not(feature = "cortex-m"))]
349339
/// # bbqtest();
350340
/// # }
351341
/// ```
352342
pub fn grant_exact(&mut self, sz: usize) -> Result<GrantW<'a, N>> {
353343
let inner = unsafe { &self.bbq.as_ref() };
354344

355-
if atomic::swap(&inner.write_in_progress, true, AcqRel) {
345+
if inner.write_in_progress.swap(true, AcqRel) {
356346
return Err(Error::GrantInProgress);
357347
}
358348

@@ -443,14 +433,13 @@ impl<'a, const N: usize> Producer<'a, N> {
443433
/// # }
444434
/// #
445435
/// # fn main() {
446-
/// # #[cfg(not(feature = "cortex-m"))]
447436
/// # bbqtest();
448437
/// # }
449438
/// ```
450439
pub fn grant_max_remaining(&mut self, mut sz: usize) -> Result<GrantW<'a, N>> {
451440
let inner = unsafe { &self.bbq.as_ref() };
452441

453-
if atomic::swap(&inner.write_in_progress, true, AcqRel) {
442+
if inner.write_in_progress.swap(true, AcqRel) {
454443
return Err(Error::GrantInProgress);
455444
}
456445

@@ -548,14 +537,13 @@ impl<'a, const N: usize> Consumer<'a, N> {
548537
/// # }
549538
/// #
550539
/// # fn main() {
551-
/// # #[cfg(not(feature = "cortex-m"))]
552540
/// # bbqtest();
553541
/// # }
554542
/// ```
555543
pub fn read(&mut self) -> Result<GrantR<'a, N>> {
556544
let inner = unsafe { &self.bbq.as_ref() };
557545

558-
if atomic::swap(&inner.read_in_progress, true, AcqRel) {
546+
if inner.read_in_progress.swap(true, AcqRel) {
559547
return Err(Error::GrantInProgress);
560548
}
561549

@@ -607,7 +595,7 @@ impl<'a, const N: usize> Consumer<'a, N> {
607595
pub fn split_read(&mut self) -> Result<SplitGrantR<'a, N>> {
608596
let inner = unsafe { &self.bbq.as_ref() };
609597

610-
if atomic::swap(&inner.read_in_progress, true, AcqRel) {
598+
if inner.read_in_progress.swap(true, AcqRel) {
611599
return Err(Error::GrantInProgress);
612600
}
613601

@@ -674,7 +662,6 @@ impl<const N: usize> BBBuffer<N> {
674662
/// # }
675663
/// #
676664
/// # fn main() {
677-
/// # #[cfg(not(feature = "cortex-m"))]
678665
/// # bbqtest();
679666
/// # }
680667
/// ```
@@ -690,9 +677,6 @@ impl<const N: usize> BBBuffer<N> {
690677
/// the contents, or by setting a the number of bytes to
691678
/// automatically be committed with `to_commit()`, then no bytes
692679
/// will be comitted for writing.
693-
///
694-
/// If the `cortex-m` feature is selected, dropping the grant
695-
/// without committing it takes a short critical section,
696680
#[derive(Debug, PartialEq)]
697681
pub struct GrantW<'a, const N: usize> {
698682
pub(crate) buf: &'a mut [u8],
@@ -710,10 +694,6 @@ unsafe impl<'a, const N: usize> Send for GrantW<'a, N> {}
710694
/// the contents, or by setting the number of bytes to automatically
711695
/// be released with `to_release()`, then no bytes will be released
712696
/// as read.
713-
///
714-
///
715-
/// If the `cortex-m` feature is selected, dropping the grant
716-
/// without releasing it takes a short critical section,
717697
#[derive(Debug, PartialEq)]
718698
pub struct GrantR<'a, const N: usize> {
719699
pub(crate) buf: &'a mut [u8],
@@ -743,9 +723,6 @@ impl<'a, const N: usize> GrantW<'a, N> {
743723
///
744724
/// If `used` is larger than the given grant, the maximum amount will
745725
/// be commited
746-
///
747-
/// NOTE: If the `cortex-m` feature is selected, this function takes a short critical
748-
/// section while committing.
749726
pub fn commit(mut self, used: usize) {
750727
self.commit_inner(used);
751728
forget(self);
@@ -770,7 +747,6 @@ impl<'a, const N: usize> GrantW<'a, N> {
770747
/// # }
771748
/// #
772749
/// # fn main() {
773-
/// # #[cfg(not(feature = "cortex-m"))]
774750
/// # bbqtest();
775751
/// # }
776752
/// ```
@@ -814,7 +790,7 @@ impl<'a, const N: usize> GrantW<'a, N> {
814790
let used = min(len, used);
815791

816792
let write = inner.write.load(Acquire);
817-
atomic::fetch_sub(&inner.reserve, len - used, AcqRel);
793+
inner.reserve.fetch_sub(len - used, AcqRel);
818794

819795
let max = N;
820796
let last = inner.last.load(Acquire);
@@ -860,9 +836,6 @@ impl<'a, const N: usize> GrantR<'a, N> {
860836
///
861837
/// If `used` is larger than the given grant, the full grant will
862838
/// be released.
863-
///
864-
/// NOTE: If the `cortex-m` feature is selected, this function takes a short critical
865-
/// section while releasing.
866839
pub fn release(mut self, used: usize) {
867840
// Saturate the grant release
868841
let used = min(self.buf.len(), used);
@@ -903,7 +876,6 @@ impl<'a, const N: usize> GrantR<'a, N> {
903876
/// # }
904877
/// #
905878
/// # fn main() {
906-
/// # #[cfg(not(feature = "cortex-m"))]
907879
/// # bbqtest();
908880
/// # }
909881
/// ```
@@ -951,7 +923,7 @@ impl<'a, const N: usize> GrantR<'a, N> {
951923
debug_assert!(used <= self.buf.len());
952924

953925
// This should be fine, purely incrementing
954-
let _ = atomic::fetch_add(&inner.read, used, Release);
926+
let _ = inner.read.fetch_add(used, Release);
955927

956928
inner.read_in_progress.store(false, Release);
957929
}
@@ -968,9 +940,6 @@ impl<'a, const N: usize> SplitGrantR<'a, N> {
968940
///
969941
/// If `used` is larger than the given grant, the full grant will
970942
/// be released.
971-
///
972-
/// NOTE: If the `cortex-m` feature is selected, this function takes a short critical
973-
/// section while releasing.
974943
pub fn release(mut self, used: usize) {
975944
// Saturate the grant release
976945
let used = min(self.combined_len(), used);
@@ -1004,7 +973,6 @@ impl<'a, const N: usize> SplitGrantR<'a, N> {
1004973
/// # }
1005974
/// #
1006975
/// # fn main() {
1007-
/// # #[cfg(not(feature = "cortex-m"))]
1008976
/// # bbqtest();
1009977
/// # }
1010978
/// ```
@@ -1036,7 +1004,7 @@ impl<'a, const N: usize> SplitGrantR<'a, N> {
10361004

10371005
if used <= self.buf1.len() {
10381006
// This should be fine, purely incrementing
1039-
let _ = atomic::fetch_add(&inner.read, used, Release);
1007+
let _ = inner.read.fetch_add(used, Release);
10401008
} else {
10411009
// Also release parts of the second buffer
10421010
inner.read.store(used - self.buf1.len(), Release);
@@ -1101,59 +1069,3 @@ impl<'a, const N: usize> DerefMut for GrantR<'a, N> {
11011069
self.buf
11021070
}
11031071
}
1104-
1105-
#[cfg(feature = "cortex-m")]
1106-
mod atomic {
1107-
use core::sync::atomic::{
1108-
AtomicBool, AtomicUsize,
1109-
Ordering::{self, Acquire, Release},
1110-
};
1111-
use cortex_m::interrupt::free;
1112-
1113-
#[inline(always)]
1114-
pub fn fetch_add(atomic: &AtomicUsize, val: usize, _order: Ordering) -> usize {
1115-
free(|_| {
1116-
let prev = atomic.load(Acquire);
1117-
atomic.store(prev.wrapping_add(val), Release);
1118-
prev
1119-
})
1120-
}
1121-
1122-
#[inline(always)]
1123-
pub fn fetch_sub(atomic: &AtomicUsize, val: usize, _order: Ordering) -> usize {
1124-
free(|_| {
1125-
let prev = atomic.load(Acquire);
1126-
atomic.store(prev.wrapping_sub(val), Release);
1127-
prev
1128-
})
1129-
}
1130-
1131-
#[inline(always)]
1132-
pub fn swap(atomic: &AtomicBool, val: bool, _order: Ordering) -> bool {
1133-
free(|_| {
1134-
let prev = atomic.load(Acquire);
1135-
atomic.store(val, Release);
1136-
prev
1137-
})
1138-
}
1139-
}
1140-
1141-
#[cfg(not(feature = "cortex-m"))]
1142-
mod atomic {
1143-
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
1144-
1145-
#[inline(always)]
1146-
pub fn fetch_add(atomic: &AtomicUsize, val: usize, order: Ordering) -> usize {
1147-
atomic.fetch_add(val, order)
1148-
}
1149-
1150-
#[inline(always)]
1151-
pub fn fetch_sub(atomic: &AtomicUsize, val: usize, order: Ordering) -> usize {
1152-
atomic.fetch_sub(val, order)
1153-
}
1154-
1155-
#[inline(always)]
1156-
pub fn swap(atomic: &AtomicBool, val: bool, order: Ordering) -> bool {
1157-
atomic.swap(val, order)
1158-
}
1159-
}

core/src/framed.rs

-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
//! # }
3535
//! #
3636
//! # fn main() {
37-
//! # #[cfg(not(feature = "cortex-m"))]
3837
//! # bbqtest();
3938
//! # }
4039
//! ```

core/src/lib.rs

-11
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,6 @@
8383
//! assert!(BB.try_split().is_err());
8484
//! }
8585
//! ```
86-
//!
87-
//! ## Features
88-
//!
89-
//! By default BBQueue uses atomic operations which are available on most platforms. However on some
90-
//! (mostly embedded) platforms atomic support is limited and with the default features you will get
91-
//! a compiler error about missing atomic methods.
92-
//!
93-
//! This crate contains special support for Cortex-M0(+) targets with the `cortex-m` feature. By
94-
//! enabling the feature, unsupported atomic operations will be replaced with critical sections
95-
//! implemented by disabling interrupts. The critical sections are very short, a few instructions at
96-
//! most, so they should make no difference to most applications.
9786
9887
#![cfg_attr(not(feature = "std"), no_std)]
9988
#![deny(missing_docs)]

0 commit comments

Comments
 (0)