use core::pin::pin;
use core::sync::atomic::Ordering::*;
use core::{
cell::UnsafeCell,
marker::PhantomData,
mem,
ops::{Deref, DerefMut},
pin::Pin,
ptr,
sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize},
task::{Poll, Waker},
};
use alloc::boxed::Box;
pub type AtomicNode<T> = AtomicPtr<Node<T>>;
pub struct Queue<T> {
head: AtomicNode<T>,
tail: AtomicNode<T>,
len: AtomicUsize,
}
pub struct Node<T> {
val: T,
next: AtomicNode<T>,
}
impl<T: Send> Queue<T> {
pub fn len(&self) -> usize {
self.len.load(Acquire)
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub const fn new() -> Self {
Self {
head: AtomicPtr::new(ptr::null_mut()),
tail: AtomicPtr::new(ptr::null_mut()),
len: AtomicUsize::new(0),
}
}
pub unsafe fn enqueue(&self, value: T) {
let node = Box::into_raw(Box::new(Node {
val: value,
next: AtomicPtr::new(ptr::null_mut()),
}));
loop {
let tail = self.tail.load(Acquire);
if tail.is_null() {
if let Ok(_) =
self.head
.compare_exchange_weak(ptr::null_mut(), node, Release, Acquire)
{
self.tail.store(node, Release);
self.len.fetch_add(1, AcqRel);
return;
}
continue;
}
if let Ok(_) =
(*tail)
.next
.compare_exchange_weak(ptr::null_mut(), node, Release, Acquire)
{
self.tail.store(node, Release);
self.len.fetch_add(1, AcqRel);
return;
}
}
}
pub unsafe fn dequeue(&self) -> Option<T> {
loop {
let head = self.head.load(Acquire);
if head.is_null() {
return None;
}
let next = (*head).next.load(Acquire);
if let Ok(_) = self
.head
.compare_exchange_weak(head, next, Release, Acquire)
{
if next.is_null() {
self.tail.store(ptr::null_mut(), Release);
}
let node = Box::from_raw(head);
self.len.fetch_sub(1, AcqRel);
return Some(node.val);
}
}
}
}