Skip to content

Commit 930b496

Browse files
bors[bot]japaric
andcommitted
Merge #47
47: RingBuffer: put smaller atomic indices behind a Cargo feature r=japaric a=japaric cc #40 Co-authored-by: Jorge Aparicio <[email protected]>
2 parents f1b58a8 + ae808c9 commit 930b496

File tree

4 files changed

+81
-16
lines changed

4 files changed

+81
-16
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

+76-14
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,53 @@ mod spsc;
1418

1519
/// Types that can be used as `RingBuffer` indices: `u8`, `u16` and `usize
1620
///
17-
/// Do not implement this trait yourself
18-
pub unsafe trait Uxx: Into<usize> + Send {
21+
/// This trait is sealed and cannot be implemented outside of `heapless`.
22+
pub unsafe trait Uxx: Into<usize> + Send + private::Sealed {
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+
mod private {
58+
pub trait Sealed {}
59+
60+
impl Sealed for usize {}
61+
#[cfg(feature = "smaller-atomics")]
62+
impl Sealed for u8 {}
63+
#[cfg(feature = "smaller-atomics")]
64+
impl Sealed for u16 {}
65+
}
66+
67+
#[cfg(feature = "smaller-atomics")]
2368
unsafe impl Uxx for u8 {
2469
fn truncate(x: usize) -> Self {
2570
let max = ::core::u8::MAX;
@@ -31,6 +76,7 @@ unsafe impl Uxx for u8 {
3176
}
3277
}
3378

79+
#[cfg(feature = "smaller-atomics")]
3480
unsafe impl Uxx for u16 {
3581
fn truncate(x: usize) -> Self {
3682
let max = ::core::u16::MAX;
@@ -46,6 +92,23 @@ unsafe impl Uxx for usize {
4692
fn truncate(x: usize) -> Self {
4793
x
4894
}
95+
96+
#[cfg(not(feature = "smaller-atomics"))]
97+
fn load_acquire(x: *mut Self) -> Self {
98+
unsafe { (*(x as *mut AtomicUsize)).load(Ordering::Acquire) }
99+
}
100+
101+
#[cfg(not(feature = "smaller-atomics"))]
102+
fn load_relaxed(x: *mut Self) -> Self {
103+
unsafe { (*(x as *mut AtomicUsize)).load(Ordering::Relaxed) }
104+
}
105+
106+
#[cfg(not(feature = "smaller-atomics"))]
107+
fn store_release(x: *mut Self, val: Self) {
108+
unsafe {
109+
(*(x as *mut AtomicUsize)).store(val, Ordering::Release);
110+
}
111+
}
49112
}
50113

51114
// Atomic{U8,U16, Usize} with no CAS operations that works on targets that have "no atomic support"
@@ -61,28 +124,26 @@ impl<U> Atomic<U>
61124
where
62125
U: Uxx,
63126
{
64-
const_fn!(
65-
const fn new(v: U) -> Atomic<U> {
66-
Atomic {
67-
v: UnsafeCell::new(v),
68-
}
127+
const_fn!(const fn new(v: U) -> Atomic<U> {
128+
Atomic {
129+
v: UnsafeCell::new(v),
69130
}
70-
);
131+
});
71132

72133
fn get_mut(&mut self) -> &mut U {
73134
unsafe { &mut *self.v.get() }
74135
}
75136

76137
fn load_acquire(&self) -> U {
77-
unsafe { intrinsics::atomic_load_acq(self.v.get()) }
138+
U::load_acquire(self.v.get())
78139
}
79140

80141
fn load_relaxed(&self) -> U {
81-
unsafe { intrinsics::atomic_load_relaxed(self.v.get()) }
142+
U::load_relaxed(self.v.get())
82143
}
83144

84145
fn store_release(&self, val: U) {
85-
unsafe { intrinsics::atomic_store_rel(self.v.get(), val) }
146+
U::store_release(self.v.get(), val)
86147
}
87148
}
88149

@@ -269,7 +330,6 @@ macro_rules! impl_ {
269330
N: Add<U1> + Unsigned,
270331
Sum<N, U1>: ArrayLength<T>,
271332
{
272-
273333
const_fn!(
274334
/// Creates an empty ring buffer with a fixed capacity of `N`
275335
pub const fn $uxx() -> Self {
@@ -357,7 +417,6 @@ where
357417
N: Add<U1> + Unsigned,
358418
Sum<N, U1>: ArrayLength<T>,
359419
{
360-
361420
const_fn!(
362421
/// Alias for [`RingBuffer::usize`](struct.RingBuffer.html#method.usize)
363422
pub const fn new() -> Self {
@@ -366,7 +425,9 @@ where
366425
);
367426
}
368427

428+
#[cfg(feature = "smaller-atomics")]
369429
impl_!(u8);
430+
#[cfg(feature = "smaller-atomics")]
370431
impl_!(u16);
371432
impl_!(usize);
372433

@@ -548,6 +609,7 @@ mod tests {
548609
}
549610

550611
#[test]
612+
#[cfg(feature = "smaller-atomics")]
551613
fn u8() {
552614
let mut rb: RingBuffer<u8, U256, _> = RingBuffer::u8();
553615

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)