mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-02 14:54:30 +00:00
RingBuffer: put smaller atomic indices behind a Cargo feature
this let us drop the core_intrinsics feature gate
This commit is contained in:
parent
f1b58a8d67
commit
ddc6842342
@ -19,8 +19,9 @@ repository = "https://github.com/japaric/heapless"
|
|||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["const-fn"]
|
default = ["const-fn", "smaller-atomics"]
|
||||||
const-fn = []
|
const-fn = []
|
||||||
|
smaller-atomics = []
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
scoped_threadpool = "0.1.8"
|
scoped_threadpool = "0.1.8"
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
#![cfg_attr(feature = "const-fn", feature(const_fn))]
|
#![cfg_attr(feature = "const-fn", feature(const_fn))]
|
||||||
#![feature(core_intrinsics)]
|
#![cfg_attr(feature = "smaller-atomics", feature(core_intrinsics))]
|
||||||
#![feature(untagged_unions)]
|
#![feature(untagged_unions)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
//! Ring buffer
|
//! Ring buffer
|
||||||
|
|
||||||
use core::cell::UnsafeCell;
|
use core::cell::UnsafeCell;
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
|
use core::intrinsics;
|
||||||
use core::ops::Add;
|
use core::ops::Add;
|
||||||
use core::{intrinsics, ptr};
|
use core::ptr;
|
||||||
|
#[cfg(not(feature = "smaller-atomics"))]
|
||||||
|
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
use generic_array::typenum::{Sum, U1, Unsigned};
|
use generic_array::typenum::{Sum, U1, Unsigned};
|
||||||
use generic_array::{ArrayLength, GenericArray};
|
use generic_array::{ArrayLength, GenericArray};
|
||||||
@ -14,12 +18,43 @@ mod spsc;
|
|||||||
|
|
||||||
/// Types that can be used as `RingBuffer` indices: `u8`, `u16` and `usize
|
/// Types that can be used as `RingBuffer` indices: `u8`, `u16` and `usize
|
||||||
///
|
///
|
||||||
/// Do not implement this trait yourself
|
/// This trait is sealed and cannot be implemented outside of `heapless`.
|
||||||
pub unsafe trait Uxx: Into<usize> + Send {
|
pub unsafe trait Uxx: Into<usize> + Send {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn truncate(x: usize) -> Self;
|
fn truncate(x: usize) -> Self;
|
||||||
|
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn load_acquire(x: *mut Self) -> Self {
|
||||||
|
unsafe { intrinsics::atomic_load_acq(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "smaller-atomics"))]
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn load_acquire(x: *mut Self) -> Self;
|
||||||
|
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn load_relaxed(x: *mut Self) -> Self {
|
||||||
|
unsafe { intrinsics::atomic_load_relaxed(x) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "smaller-atomics"))]
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn load_relaxed(x: *mut Self) -> Self;
|
||||||
|
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn store_release(x: *mut Self, val: Self) {
|
||||||
|
unsafe { intrinsics::atomic_store_rel(x, val) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "smaller-atomics"))]
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn store_release(x: *mut Self, val: Self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
unsafe impl Uxx for u8 {
|
unsafe impl Uxx for u8 {
|
||||||
fn truncate(x: usize) -> Self {
|
fn truncate(x: usize) -> Self {
|
||||||
let max = ::core::u8::MAX;
|
let max = ::core::u8::MAX;
|
||||||
@ -31,6 +66,7 @@ unsafe impl Uxx for u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
unsafe impl Uxx for u16 {
|
unsafe impl Uxx for u16 {
|
||||||
fn truncate(x: usize) -> Self {
|
fn truncate(x: usize) -> Self {
|
||||||
let max = ::core::u16::MAX;
|
let max = ::core::u16::MAX;
|
||||||
@ -46,6 +82,23 @@ unsafe impl Uxx for usize {
|
|||||||
fn truncate(x: usize) -> Self {
|
fn truncate(x: usize) -> Self {
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "smaller-atomics"))]
|
||||||
|
fn load_acquire(x: *mut Self) -> Self {
|
||||||
|
unsafe { (*(x as *mut AtomicUsize)).load(Ordering::Acquire) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "smaller-atomics"))]
|
||||||
|
fn load_relaxed(x: *mut Self) -> Self {
|
||||||
|
unsafe { (*(x as *mut AtomicUsize)).load(Ordering::Relaxed) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "smaller-atomics"))]
|
||||||
|
fn store_release(x: *mut Self, val: Self) {
|
||||||
|
unsafe {
|
||||||
|
(*(x as *mut AtomicUsize)).store(val, Ordering::Release);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Atomic{U8,U16, Usize} with no CAS operations that works on targets that have "no atomic support"
|
// 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>
|
|||||||
where
|
where
|
||||||
U: Uxx,
|
U: Uxx,
|
||||||
{
|
{
|
||||||
const_fn!(
|
const_fn!(const fn new(v: U) -> Atomic<U> {
|
||||||
const fn new(v: U) -> Atomic<U> {
|
Atomic {
|
||||||
Atomic {
|
v: UnsafeCell::new(v),
|
||||||
v: UnsafeCell::new(v),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
fn get_mut(&mut self) -> &mut U {
|
fn get_mut(&mut self) -> &mut U {
|
||||||
unsafe { &mut *self.v.get() }
|
unsafe { &mut *self.v.get() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_acquire(&self) -> U {
|
fn load_acquire(&self) -> U {
|
||||||
unsafe { intrinsics::atomic_load_acq(self.v.get()) }
|
U::load_acquire(self.v.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_relaxed(&self) -> U {
|
fn load_relaxed(&self) -> U {
|
||||||
unsafe { intrinsics::atomic_load_relaxed(self.v.get()) }
|
U::load_relaxed(self.v.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store_release(&self, val: U) {
|
fn store_release(&self, val: U) {
|
||||||
unsafe { intrinsics::atomic_store_rel(self.v.get(), val) }
|
U::store_release(self.v.get(), val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +320,6 @@ macro_rules! impl_ {
|
|||||||
N: Add<U1> + Unsigned,
|
N: Add<U1> + Unsigned,
|
||||||
Sum<N, U1>: ArrayLength<T>,
|
Sum<N, U1>: ArrayLength<T>,
|
||||||
{
|
{
|
||||||
|
|
||||||
const_fn!(
|
const_fn!(
|
||||||
/// Creates an empty ring buffer with a fixed capacity of `N`
|
/// Creates an empty ring buffer with a fixed capacity of `N`
|
||||||
pub const fn $uxx() -> Self {
|
pub const fn $uxx() -> Self {
|
||||||
@ -357,7 +407,6 @@ where
|
|||||||
N: Add<U1> + Unsigned,
|
N: Add<U1> + Unsigned,
|
||||||
Sum<N, U1>: ArrayLength<T>,
|
Sum<N, U1>: ArrayLength<T>,
|
||||||
{
|
{
|
||||||
|
|
||||||
const_fn!(
|
const_fn!(
|
||||||
/// Alias for [`RingBuffer::usize`](struct.RingBuffer.html#method.usize)
|
/// Alias for [`RingBuffer::usize`](struct.RingBuffer.html#method.usize)
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
@ -366,7 +415,9 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
impl_!(u8);
|
impl_!(u8);
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
impl_!(u16);
|
impl_!(u16);
|
||||||
impl_!(usize);
|
impl_!(usize);
|
||||||
|
|
||||||
@ -548,6 +599,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
fn u8() {
|
fn u8() {
|
||||||
let mut rb: RingBuffer<u8, U256, _> = RingBuffer::u8();
|
let mut rb: RingBuffer<u8, U256, _> = RingBuffer::u8();
|
||||||
|
|
||||||
|
@ -196,7 +196,9 @@ macro_rules! impl_ {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
impl_!(u8);
|
impl_!(u8);
|
||||||
|
#[cfg(feature = "smaller-atomics")]
|
||||||
impl_!(u16);
|
impl_!(u16);
|
||||||
impl_!(usize);
|
impl_!(usize);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user