Skip to content

Commit ddc6842

Browse files
committed
RingBuffer: put smaller atomic indices behind a Cargo feature
this let us drop the core_intrinsics feature gate
1 parent f1b58a8 commit ddc6842

File tree

4 files changed

+70
-15
lines changed

4 files changed

+70
-15
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ repository = "https://github.com/japaric/heapless"
1919
version = "0.3.6"
2020

2121
[features]
22-
default = ["const-fn"]
22+
default = ["const-fn", "smaller-atomics"]
2323
const-fn = []
24+
smaller-atomics = []
2425

2526
[dev-dependencies]
2627
scoped_threadpool = "0.1.8"

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
#![deny(missing_docs)]
8484
#![deny(warnings)]
8585
#![cfg_attr(feature = "const-fn", feature(const_fn))]
86-
#![feature(core_intrinsics)]
86+
#![cfg_attr(feature = "smaller-atomics", feature(core_intrinsics))]
8787
#![feature(untagged_unions)]
8888
#![no_std]
8989

src/ring_buffer/mod.rs

+65-13
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
//! Ring buffer
22
33
use core::cell::UnsafeCell;
4+
#[cfg(feature = "smaller-atomics")]
5+
use core::intrinsics;
46
use core::ops::Add;
5-
use core::{intrinsics, ptr};
7+
use core::ptr;
8+
#[cfg(not(feature = "smaller-atomics"))]
9+
use core::sync::atomic::{AtomicUsize, Ordering};
610

711
use generic_array::typenum::{Sum, U1, Unsigned};
812
use generic_array::{ArrayLength, GenericArray};
@@ -14,12 +18,43 @@ mod spsc;
1418

1519
/// Types that can be used as `RingBuffer` indices: `u8`, `u16` and `usize
1620
///
17-
/// Do not implement this trait yourself
21+
/// This trait is sealed and cannot be implemented outside of `heapless`.
1822
pub unsafe trait Uxx: Into<usize> + Send {
1923
#[doc(hidden)]
2024
fn truncate(x: usize) -> Self;
25+
26+
#[cfg(feature = "smaller-atomics")]
27+
#[doc(hidden)]
28+
fn load_acquire(x: *mut Self) -> Self {
29+
unsafe { intrinsics::atomic_load_acq(x) }
30+
}
31+
32+
#[cfg(not(feature = "smaller-atomics"))]
33+
#[doc(hidden)]
34+
fn load_acquire(x: *mut Self) -> Self;
35+
36+
#[cfg(feature = "smaller-atomics")]
37+
#[doc(hidden)]
38+
fn load_relaxed(x: *mut Self) -> Self {
39+
unsafe { intrinsics::atomic_load_relaxed(x) }
40+
}
41+
42+
#[cfg(not(feature = "smaller-atomics"))]
43+
#[doc(hidden)]
44+
fn load_relaxed(x: *mut Self) -> Self;
45+
46+
#[cfg(feature = "smaller-atomics")]
47+
#[doc(hidden)]
48+
fn store_release(x: *mut Self, val: Self) {
49+
unsafe { intrinsics::atomic_store_rel(x, val) }
50+
}
51+
52+
#[cfg(not(feature = "smaller-atomics"))]
53+
#[doc(hidden)]
54+
fn store_release(x: *mut Self, val: Self);
2155
}
2256

57+
#[cfg(feature = "smaller-atomics")]
2358
unsafe impl Uxx for u8 {
2459
fn truncate(x: usize) -> Self {
2560
let max = ::core::u8::MAX;
@@ -31,6 +66,7 @@ unsafe impl Uxx for u8 {
3166
}
3267
}
3368

69+
#[cfg(feature = "smaller-atomics")]
3470
unsafe impl Uxx for u16 {
3571
fn truncate(x: usize) -> Self {
3672
let max = ::core::u16::MAX;
@@ -46,6 +82,23 @@ unsafe impl Uxx for usize {
4682
fn truncate(x: usize) -> Self {
4783
x
4884
}
85+
86+
#[cfg(not(feature = "smaller-atomics"))]
87+
fn load_acquire(x: *mut Self) -> Self {
88+
unsafe { (*(x as *mut AtomicUsize)).load(Ordering::Acquire) }
89+
}
90+
91+
#[cfg(not(feature = "smaller-atomics"))]
92+
fn load_relaxed(x: *mut Self) -> Self {
93+
unsafe { (*(x as *mut AtomicUsize)).load(Ordering::Relaxed) }
94+
}
95+
96+
#[cfg(not(feature = "smaller-atomics"))]
97+
fn store_release(x: *mut Self, val: Self) {
98+
unsafe {
99+
(*(x as *mut AtomicUsize)).store(val, Ordering::Release);
100+
}
101+
}
49102
}
50103

51104
// Atomic{U8,U16, Usize} with no CAS operations that works on targets that have "no atomic support"
@@ -61,28 +114,26 @@ impl<U> Atomic<U>
61114
where
62115
U: Uxx,
63116
{
64-
const_fn!(
65-
const fn new(v: U) -> Atomic<U> {
66-
Atomic {
67-
v: UnsafeCell::new(v),
68-
}
117+
const_fn!(const fn new(v: U) -> Atomic<U> {
118+
Atomic {
119+
v: UnsafeCell::new(v),
69120
}
70-
);
121+
});
71122

72123
fn get_mut(&mut self) -> &mut U {
73124
unsafe { &mut *self.v.get() }
74125
}
75126

76127
fn load_acquire(&self) -> U {
77-
unsafe { intrinsics::atomic_load_acq(self.v.get()) }
128+
U::load_acquire(self.v.get())
78129
}
79130

80131
fn load_relaxed(&self) -> U {
81-
unsafe { intrinsics::atomic_load_relaxed(self.v.get()) }
132+
U::load_relaxed(self.v.get())
82133
}
83134

84135
fn store_release(&self, val: U) {
85-
unsafe { intrinsics::atomic_store_rel(self.v.get(), val) }
136+
U::store_release(self.v.get(), val)
86137
}
87138
}
88139

@@ -269,7 +320,6 @@ macro_rules! impl_ {
269320
N: Add<U1> + Unsigned,
270321
Sum<N, U1>: ArrayLength<T>,
271322
{
272-
273323
const_fn!(
274324
/// Creates an empty ring buffer with a fixed capacity of `N`
275325
pub const fn $uxx() -> Self {
@@ -357,7 +407,6 @@ where
357407
N: Add<U1> + Unsigned,
358408
Sum<N, U1>: ArrayLength<T>,
359409
{
360-
361410
const_fn!(
362411
/// Alias for [`RingBuffer::usize`](struct.RingBuffer.html#method.usize)
363412
pub const fn new() -> Self {
@@ -366,7 +415,9 @@ where
366415
);
367416
}
368417

418+
#[cfg(feature = "smaller-atomics")]
369419
impl_!(u8);
420+
#[cfg(feature = "smaller-atomics")]
370421
impl_!(u16);
371422
impl_!(usize);
372423

@@ -548,6 +599,7 @@ mod tests {
548599
}
549600

550601
#[test]
602+
#[cfg(feature = "smaller-atomics")]
551603
fn u8() {
552604
let mut rb: RingBuffer<u8, U256, _> = RingBuffer::u8();
553605

src/ring_buffer/spsc.rs

+2
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ macro_rules! impl_ {
196196
};
197197
}
198198

199+
#[cfg(feature = "smaller-atomics")]
199200
impl_!(u8);
201+
#[cfg(feature = "smaller-atomics")]
200202
impl_!(u16);
201203
impl_!(usize);
202204

0 commit comments

Comments
 (0)