use super::crossbeam::sync::{TreiberStack, SegQueue, MsQueue};
use super::crossbeam::mem::epoch;
use std::sync::atomic::AtomicUsize;
use std::sync::Arc;
pub enum PopStatus {
Empty,
TransientFailure,
}
pub type PopResult<T> = Result<T, PopStatus>;
pub trait SharedWeakBag {
type Item;
fn new() -> Self;
fn try_push(&self, it: Self::Item) -> Result<(), Self::Item>;
fn try_pop(&self) -> PopResult<Self::Item>;
fn push(&self, it: Self::Item) {
let _g = epoch::pin();
let mut cur_item = it;
while let Err(old_item) = self.try_push(cur_item) {
cur_item = old_item
}
}
fn pop(&self) -> Option<Self::Item> {
let _g = epoch::pin();
loop {
return match self.try_pop() {
Ok(it) => Some(it),
Err(PopStatus::Empty) => None,
Err(PopStatus::TransientFailure) => continue,
};
}
}
fn debug(&self) {}
}
pub trait WeakBag: Clone {
type Item;
fn new() -> Self;
fn try_push_mut(&mut self, Self::Item) -> Result<(), Self::Item>;
fn try_pop_mut(&mut self) -> PopResult<Self::Item>;
fn push_mut(&mut self, it: Self::Item) {
let _g = epoch::pin();
let mut cur_item = it;
while let Err(old_item) = self.try_push_mut(cur_item) {
cur_item = old_item
}
}
fn pop_mut(&mut self) -> Option<Self::Item> {
let _g = epoch::pin();
loop {
return match self.try_pop_mut() {
Ok(it) => Some(it),
Err(PopStatus::Empty) => None,
Err(PopStatus::TransientFailure) => continue,
};
}
}
fn bulk_add<I: Iterator<Item = Self::Item>>(&mut self, i: I) {
for it in i {
self.push_mut(it)
}
}
}
impl<B: SharedWeakBag> WeakBag for Arc<B> {
type Item = B::Item;
fn new() -> Self {
Arc::new(B::new())
}
fn try_push_mut(&mut self, it: Self::Item) -> Result<(), Self::Item> {
self.try_push(it)
}
fn try_pop_mut(&mut self) -> PopResult<Self::Item> {
self.try_pop()
}
}
pub trait Revocable {
fn handle(&self) -> &AtomicUsize;
}
impl<T: Revocable> Revocable for *mut T {
fn handle(&self) -> &AtomicUsize {
unsafe {
self.as_ref()
.expect("revocable impl dereferences raw pointers")
.handle()
}
}
}
pub trait RevocableWeakBag: SharedWeakBag
where Self::Item: Revocable
{
unsafe fn revoke(it: &Self::Item) -> bool;
}
impl<T> SharedWeakBag for TreiberStack<T> {
type Item = T;
fn new() -> Self {
Self::new()
}
fn try_push(&self, t: T) -> Result<(), T> {
self.push(t);
Ok(())
}
fn try_pop(&self) -> PopResult<T> {
match self.pop() {
Some(res) => Ok(res),
None => Err(PopStatus::Empty),
}
}
}
impl<T> SharedWeakBag for SegQueue<T> {
type Item = T;
fn new() -> Self {
Self::new()
}
fn try_push(&self, t: T) -> Result<(), T> {
self.push(t);
Ok(())
}
fn try_pop(&self) -> PopResult<T> {
match self.try_pop() {
Some(res) => Ok(res),
None => Err(PopStatus::Empty),
}
}
}
impl<T> SharedWeakBag for MsQueue<T> {
type Item = T;
fn new() -> Self {
Self::new()
}
fn try_push(&self, t: T) -> Result<(), T> {
self.push(t);
Ok(())
}
fn try_pop(&self) -> PopResult<T> {
match self.try_pop() {
Some(res) => Ok(res),
None => Err(PopStatus::Empty),
}
}
}