From 492717a7d2274d5c5020f0a80342ba0f365ccc67 Mon Sep 17 00:00:00 2001 From: ticki Date: Sun, 4 Jun 2017 23:52:59 +0200 Subject: [PATCH] Initial implementation of treiber stacks for `conc`. --- conc/src/sync/treiber.rs | 56 +++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/conc/src/sync/treiber.rs b/conc/src/sync/treiber.rs index c669217..9111644 100644 --- a/conc/src/sync/treiber.rs +++ b/conc/src/sync/treiber.rs @@ -1,37 +1,57 @@ -pub struct Treiber; +use std::sync::atomic; +use Atomic; -/* pub struct Treiber { - head: ::Option>, + head: Atomic>, } struct Node { data: T, - next: ::Option>, + next: *mut T, } impl Treiber { - pub fn new() -> Stack { - Stack { - head: ::Option::default(), + pub fn new() -> Treiber { + Treiber { + head: Atomic::default(), } } - pub fn push(&self, item: T) -> Option { + pub fn pop(&self, item: T) -> Option<::Guard> { // TODO: Use `catch {}` here when it lands. let mut head = self.head.load(atomic::Ordering::Acquire); - loop { - if let Some(head) = { - let next = head.next + while let Some(node) = head { + // TODO: This should be something that ignores the guard creation when the CAS + // fails, because it's expensive to do and not used anyway. It should be easy + // enough to implement, but I am struggling to come up with a good name for + // the method. + match self.head.compare_and_swap_raw(head, node.next, atomic::Ordering::Release) { + Ok(_) => return node.map(|x| x.data), + Err(new_head) => head = new_head, + } + } + } - match self.head.compare_and_swap(head, next, atomic::Ordering::Release) { - Ok() - Err(new_head) => head = new_head, - } - } else { - return None; + pub fn push(&self, item: T) { + // TODO: Use `catch {}` here when it lands. + let mut head = Box::new(Node { + data: item, + next: self.head.load(atomic::Ordering::Acquire), + }); + + loop { + // TODO: This should be something that ignores the guard creation when the CAS + // succeeds, because it's expensive to do and not used anyway. It should be easy + // enough to implement, but I am struggling to come up with a good name for the + // method. + match self.head.compare_and_swap_raw(head.next, Some(head), atomic::Ordering::Release) { + Ok(_) => break, + Err((new_head, Some(node))) => { + head = node; + head.next = new_head; + }, + _ => unreachable!(), } } } } -*/