Skip to content

Commit

Permalink
Fix internal failure ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
vertexclique committed Dec 1, 2021
1 parent 6825c11 commit 2bdb70c
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 5 deletions.
14 changes: 13 additions & 1 deletion src/sync/atomics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,20 @@ impl<T: Sized> AtomicBox<T> {
Arc::into_raw(total) as *mut T
}

fn strongest_failure_ordering(order: Ordering) -> Ordering {
use Ordering::*;
match order {
Release => Relaxed,
Relaxed => Relaxed,
SeqCst => SeqCst,
Acquire => Acquire,
AcqRel => Acquire,
_ => unsafe { std::hint::unreachable_unchecked() }
}
}

fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T {
self.ptr.compare_and_swap(current, new, order)
self.ptr.compare_exchange(current, new, order, Self::strongest_failure_ordering(order)).unwrap()
}

fn take(&self) -> Arc<T> {
Expand Down
17 changes: 15 additions & 2 deletions src/sync/treiber.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::mem::ManuallyDrop;
use std::ptr;
use std::sync::atomic::Ordering::{Acquire, Relaxed, Release};
use std::sync::atomic::Ordering;

use crossbeam_epoch as epoch;
use crossbeam_epoch::{Atomic, Owned};
Expand Down Expand Up @@ -32,6 +33,18 @@ impl<T> TreiberStack<T> {
}
}

fn strongest_failure_ordering(order: Ordering) -> Ordering {
use Ordering::*;
match order {
Release => Relaxed,
Relaxed => Relaxed,
SeqCst => SeqCst,
Acquire => Acquire,
AcqRel => Acquire,
_ => unsafe { std::hint::unreachable_unchecked() }
}
}

/// Pushes a value on top of the stack.
pub fn push(&self, t: T) {
let mut n = Owned::new(Node {
Expand All @@ -45,7 +58,7 @@ impl<T> TreiberStack<T> {
let head = self.head.load(Relaxed, &guard);
n.next.store(head, Relaxed);

match self.head.compare_and_set(head, n, Release, &guard) {
match self.head.compare_exchange(head, n, Release, Self::strongest_failure_ordering(Release), &guard) {
Ok(_) => break,
Err(e) => n = e.new,
}
Expand All @@ -66,7 +79,7 @@ impl<T> TreiberStack<T> {

if self
.head
.compare_and_set(head, next, Relaxed, &guard)
.compare_exchange(head, next, Relaxed, Self::strongest_failure_ordering(Relaxed), &guard)
.is_ok()
{
unsafe {
Expand Down
5 changes: 3 additions & 2 deletions src/sync/ttas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use super::ifaces::LockIface;
use std::fmt;
use std::{
cell::UnsafeCell,
sync::atomic::{spin_loop_hint, AtomicBool, Ordering},
hint::spin_loop,
sync::atomic::{AtomicBool, Ordering},
};
use std::{
marker::PhantomData as marker,
Expand Down Expand Up @@ -149,7 +150,7 @@ where
fn lock(&self) {
'lock: loop {
while let Some(true) = Some(self.acquired.load(Ordering::SeqCst)) {
spin_loop_hint();
spin_loop();
}
if !self.acquired.swap(true, Ordering::SeqCst) {
break 'lock;
Expand Down

0 comments on commit 2bdb70c

Please sign in to comment.