mirror of
https://github.com/rust-embedded/heapless.git
synced 2025-10-03 07:14:45 +00:00
add a compiler barrier
This commit is contained in:
parent
158d19b45a
commit
978f0ee2de
@ -144,6 +144,7 @@
|
|||||||
//! is_send::<Vec<NotSend, [NotSend; 4]>>();
|
//! is_send::<Vec<NotSend, [NotSend; 4]>>();
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
|
#![cfg_attr(not(target_has_atomic = "ptr"), feature(asm))]
|
||||||
#![cfg_attr(target_has_atomic = "ptr", feature(const_atomic_usize_new))]
|
#![cfg_attr(target_has_atomic = "ptr", feature(const_atomic_usize_new))]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![feature(cfg_target_has_atomic)]
|
#![feature(cfg_target_has_atomic)]
|
||||||
|
@ -6,6 +6,14 @@ use core::sync::atomic::Ordering;
|
|||||||
use BufferFullError;
|
use BufferFullError;
|
||||||
use ring_buffer::RingBuffer;
|
use ring_buffer::RingBuffer;
|
||||||
|
|
||||||
|
// Compiler barrier
|
||||||
|
#[cfg(not(target_has_atomic = "ptr"))]
|
||||||
|
macro_rules! barrier {
|
||||||
|
() => {
|
||||||
|
unsafe { asm!("" ::: "memory") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, A> RingBuffer<T, A>
|
impl<T, A> RingBuffer<T, A>
|
||||||
where
|
where
|
||||||
A: Unsize<[T]>,
|
A: Unsize<[T]>,
|
||||||
@ -75,6 +83,12 @@ where
|
|||||||
// consumer so we inform this to the compiler using a volatile load
|
// consumer so we inform this to the compiler using a volatile load
|
||||||
if rb.head != unsafe { ptr::read_volatile(&rb.tail) } {
|
if rb.head != unsafe { ptr::read_volatile(&rb.tail) } {
|
||||||
let item = unsafe { ptr::read(buffer.get_unchecked(rb.head)) };
|
let item = unsafe { ptr::read(buffer.get_unchecked(rb.head)) };
|
||||||
|
|
||||||
|
// NOTE(barrier!) this ensures that the compiler won't place the instructions to read
|
||||||
|
// the data *before* the instructions to increment the `head` pointer -- note that this
|
||||||
|
// won't be enough on architectures that allow out of order execution
|
||||||
|
barrier!();
|
||||||
|
|
||||||
rb.head = (rb.head + 1) % n;
|
rb.head = (rb.head + 1) % n;
|
||||||
Some(item)
|
Some(item)
|
||||||
} else {
|
} else {
|
||||||
@ -146,6 +160,10 @@ where
|
|||||||
if next_tail != unsafe { ptr::read_volatile(&rb.head) } {
|
if next_tail != unsafe { ptr::read_volatile(&rb.head) } {
|
||||||
// NOTE(ptr::write) see the other `enqueue` implementation above for details
|
// NOTE(ptr::write) see the other `enqueue` implementation above for details
|
||||||
unsafe { ptr::write(buffer.get_unchecked_mut(rb.tail), item) }
|
unsafe { ptr::write(buffer.get_unchecked_mut(rb.tail), item) }
|
||||||
|
|
||||||
|
// NOTE(barrier!) see the NOTE(barrier!) above
|
||||||
|
barrier!();
|
||||||
|
|
||||||
rb.tail = next_tail;
|
rb.tail = next_tail;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user