Skip to content
Snippets Groups Projects
Commit 978f0ee2 authored by Jorge Aparicio's avatar Jorge Aparicio
Browse files

add a compiler barrier

parent 158d19b4
No related branches found
No related tags found
No related merge requests found
...@@ -144,6 +144,7 @@ ...@@ -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; ...@@ -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 ...@@ -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 ...@@ -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 {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment