Skip to content

Commit

Permalink
Bug fixes, additional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
aturon committed Aug 17, 2015
1 parent f012949 commit 22a8cdc
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 26 deletions.
22 changes: 6 additions & 16 deletions src/mem/epoch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ impl Participant {
let cur_epoch = self.epoch.load(Relaxed);
mem::swap(&mut *self.garbage.borrow_mut(), &mut local);
EPOCH.garbage[cur_epoch.wrapping_sub(1) % 3].insert(local.old);
EPOCH.garbage[cur_epoch].insert(local.cur);
EPOCH.garbage[cur_epoch % 3].insert(local.cur);
}
}

Expand Down Expand Up @@ -275,7 +275,9 @@ impl<'a, T> Shared<'a, T> {
}

unsafe fn from_owned(owned: Owned<T>) -> Shared<'a, T> {
Shared::from_ref(owned.deref())
let ret = Shared::from_ref(owned.deref());
mem::forget(owned);
ret
}

fn as_raw(&self) -> *mut T {
Expand Down Expand Up @@ -453,8 +455,7 @@ impl !Sync for Guard {}

#[cfg(test)]
mod test {
use std::mem;
use super::{Participants, with_participant, LocalEpoch, EPOCH};
use super::{Participants, EPOCH};
use super::*;

#[test]
Expand All @@ -468,18 +469,7 @@ mod test {
}

#[test]
fn smoke_local_epoch() {
LocalEpoch::new();
}

#[test]
fn smoke_with_participant() {
with_participant(|p| {})
}

#[test]
fn smoke_pin() {
fn smoke_guard() {
let g = pin();
mem::forget(g);
}
}
82 changes: 72 additions & 10 deletions src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct Node<T> {

impl<T> Queue<T> {
pub fn new() -> Queue<T> {
let mut q = Queue { head: AtomicPtr::new(), tail: AtomicPtr::new() };
let q = Queue { head: AtomicPtr::new(), tail: AtomicPtr::new() };
let sentinel = Owned::new(Node {
data: RefCell::new(None),
next: AtomicPtr::new()
Expand All @@ -27,19 +27,26 @@ impl<T> Queue<T> {
}

pub fn push(&self, t: T) {
let mut n = Some(Owned::new(Node {
let mut n = Owned::new(Node {
data: RefCell::new(Some(t)),
next: AtomicPtr::new()
}));
});
let guard = epoch::pin();
loop {
let tail = self.tail.load(Acquire, &guard).unwrap();
if let Some(next) = tail.next.load(Relaxed, &guard) {
unsafe { self.tail.cas_shared(Some(tail), Some(next), Relaxed); }
} else if let Err(owned) = tail.next.cas(None, n, Release) {
n = owned;
} else {
break;
continue;
}

match tail.next.cas_and_ref(None, n, Release, &guard) {
Ok(shared) => {
unsafe { self.tail.cas_shared(Some(tail), Some(shared), Relaxed); }
break;
}
Err(owned) => {
n = owned;
}
}
}
}
Expand All @@ -62,14 +69,69 @@ impl<T> Queue<T> {
}
}

/*
impl<T: Debug> Queue<T> {
pub fn debug(&self) {
writeln!(stderr(), "Debugging queue:");
let guard = epoch::pin();
let mut node = self.head.load(Acquire, &guard);
while let Some(n) = node {
writeln!(stderr(), "{:?}", (*n).data.borrow());
node = n.next.load(Relaxed, &guard);
}
writeln!(stderr(), "");
}
}
*/

#[cfg(test)]
mod test {
use std::thread;

use super::*;

#[test]
fn smoke_test() {
fn smoke_queue() {
let q: Queue<i32> = Queue::new();
}

#[test]
fn push_pop_1() {
let q: Queue<i32> = Queue::new();
q.push(37);
assert_eq!(q.pop(), Some(37));
}

#[test]
fn push_pop_2() {
let q: Queue<i32> = Queue::new();
q.push(37);
q.push(48);
assert_eq!(q.pop(), Some(37));
assert_eq!(q.pop(), Some(48));
}

#[test]
fn push_pop_many_seq() {
let q: Queue<i32> = Queue::new();
//q.push(3);
//assert_eq!(q.pop(), Some(3));
for i in 0..200 {
q.push(i)
}
for i in 0..200 {
assert_eq!(q.pop(), Some(i));
}
}

#[test]
fn push_pop_many_spsc() {
let q: Queue<i32> = Queue::new();
for i in 0..200 {
q.push(i)
}
for i in 0..200 {
assert_eq!(q.pop(), Some(i));
}
}
}

0 comments on commit 22a8cdc

Please sign in to comment.