Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removal of GetNextMut and Atom::replace_and_set_next #10

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 0 additions & 36 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,35 +91,6 @@ where
}
}

/// Take the current content, write it into P then do a CAS to extent this
/// Atom with the previous contents. This can be used to create a LIFO
///
/// Returns true if this set this migrated the Atom from null.
pub fn replace_and_set_next(
&self,
mut value: P,
load_order: Ordering,
cas_order: Ordering,
) -> bool
where
P: GetNextMut<NextPtr = Option<P>>,
{
let next = value.get_next() as *mut Option<P>;
let raw = value.into_raw();
// If next was set to Some(P) we want to
// assert that it was droppeds
unsafe { ptr::drop_in_place(next) };
loop {
let pcurrent = self.inner.load(load_order);
let current = unsafe { Self::inner_from_raw(pcurrent) };
unsafe { ptr::write(next, current) };
let last = self.inner.compare_and_swap(pcurrent, raw, cas_order);
if last == pcurrent {
return last.is_null();
}
}
}

/// Check to see if an atom is None
///
/// This only means that the contents was None when it was measured
Expand Down Expand Up @@ -430,10 +401,3 @@ where
})
}
}

/// This is a utility Trait that fetches the next ptr from
/// an object.
pub trait GetNextMut {
type NextPtr;
fn get_next(&mut self) -> &mut Self::NextPtr;
}
76 changes: 0 additions & 76 deletions tests/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,82 +230,6 @@ fn get_arc() {
assert_eq!(v.load(Ordering::SeqCst), 1);
}

#[derive(Debug)]
struct Link {
next: Option<Box<Link>>,
value: u32,
}

impl Link {
fn new(v: u32) -> Box<Link> {
Box::new(Link {
next: None,
value: v,
})
}
}

impl GetNextMut for Box<Link> {
type NextPtr = Option<Box<Link>>;
fn get_next(&mut self) -> &mut Option<Box<Link>> {
&mut self.next
}
}

#[test]
fn lifo() {
let atom = Atom::empty();
for i in 0..100 {
let x = atom.replace_and_set_next(Link::new(99 - i), Ordering::Relaxed, Ordering::AcqRel);
assert_eq!(x, i == 0);
}

let expected: Vec<u32> = (0..100).collect();
let mut found = Vec::new();
let mut chain = atom.take(Ordering::Acquire);
while let Some(v) = chain {
found.push(v.value);
chain = v.next;
}
assert_eq!(expected, found);
}

#[allow(dead_code)]
struct LinkCanary {
next: Option<Box<LinkCanary>>,
value: Canary,
}

impl LinkCanary {
fn new(v: Canary) -> Box<LinkCanary> {
Box::new(LinkCanary {
next: None,
value: v,
})
}
}

impl GetNextMut for Box<LinkCanary> {
type NextPtr = Option<Box<LinkCanary>>;
fn get_next(&mut self) -> &mut Option<Box<LinkCanary>> {
&mut self.next
}
}

#[test]
fn lifo_drop() {
let v = Arc::new(AtomicUsize::new(0));
let canary = Canary(v.clone());
let mut link = LinkCanary::new(canary.clone());
link.next = Some(LinkCanary::new(canary.clone()));

let atom = Atom::empty();
atom.replace_and_set_next(link, Ordering::Relaxed, Ordering::AcqRel);
assert_eq!(1, v.load(Ordering::SeqCst));
drop(atom);
assert_eq!(2, v.load(Ordering::SeqCst));
}

#[test]
fn borrow() {
let a = Atom::new(&5);
Expand Down