use core::default;
use core::pin::pin;
use core::sync::atomic::Ordering::*;
use core::sync::atomic::{AtomicU8, AtomicU16, AtomicU32, AtomicU64, 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;
use derive_more::{Deref, DerefMut};
use q::Queue;
pub mod channel;
pub mod duplex;
pub mod lazy;
pub mod lock;
pub mod map;
pub mod mutual;
pub mod once;
pub mod q;
pub mod ring;
pub mod slab;
use crate::sync;
pub struct Link {
next: AtomicPtr<Link>,
prev: AtomicPtr<Link>,
}
impl Default for Link {
fn default() -> Self {
Self {
next: Default::default(),
prev: Default::default(),
}
}
}
#[derive(Default)]
pub struct WakerCell(UnsafeCell<Option<Waker>>);
impl WakerCell {
pub fn set(&self, waker: Waker) {
unsafe { *self.0.get() = Some(waker) }
}
pub fn take(&self) -> Option<Waker> {
unsafe { (*self.0.get()).take() }
}
}
impl Deref for WakerCell {
type Target = Waker;
fn deref(&self) -> &Self::Target {
unsafe { self.0.get().as_ref().unwrap().as_ref().unwrap() }
}
}
impl DerefMut for WakerCell {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.0.get().as_mut().unwrap().as_mut().unwrap() }
}
}
pub trait Discriminant {
type Repr: Into<usize>;
fn discriminant(&self) -> Self::Repr;
}
#[const_trait]
pub trait Atomic: Sized {
type Atomic;
fn new() -> Self::Atomic;
}
pub trait AtomicOp: const Atomic {
fn fetch_or(atomic: &Self::Atomic, val: Self, order: Ordering) -> Self;
fn fetch_and(atomic: &Self::Atomic, val: Self, order: Ordering) -> Self;
fn load(atomic: &Self::Atomic, order: Ordering) -> Self;
fn store(atomic: &Self::Atomic, val: Self, order: Ordering);
fn compare_exchange(
atomic: &Self::Atomic,
current: Self,
new: Self,
success: Ordering,
failure: Ordering,
) -> Result<Self, Self>;
}
impl const Atomic for u8 {
type Atomic = AtomicU8;
fn new() -> Self::Atomic {
AtomicU8::new(0)
}
}
impl AtomicOp for u8 {
fn fetch_or(atomic: &Self::Atomic, val: Self, order: Ordering) -> Self {
atomic.fetch_or(val, order)
}
fn fetch_and(atomic: &Self::Atomic, val: Self, order: Ordering) -> Self {
atomic.fetch_and(val, order)
}
fn load(atomic: &Self::Atomic, order: Ordering) -> Self {
atomic.load(order)
}
fn store(atomic: &Self::Atomic, val: Self, order: Ordering) {
atomic.store(val, order)
}
fn compare_exchange(
atomic: &Self::Atomic,
current: Self,
new: Self,
success: Ordering,
failure: Ordering,
) -> Result<Self, Self> {
atomic.compare_exchange(current, new, success, failure)
}
}
impl const Atomic for u16 {
type Atomic = AtomicU16;
fn new() -> Self::Atomic {
AtomicU16::new(0)
}
}
impl AtomicOp for u16 {
fn fetch_or(atomic: &Self::Atomic, val: Self, order: Ordering) -> Self {
atomic.fetch_or(val, order)
}
fn fetch_and(atomic: &Self::Atomic, val: Self, order: Ordering) -> Self {
atomic.fetch_and(val, order)
}
fn load(atomic: &Self::Atomic, order: Ordering) -> Self {
atomic.load(order)
}
fn store(atomic: &Self::Atomic, val: Self, order: Ordering) {
atomic.store(val, order)
}
fn compare_exchange(
atomic: &Self::Atomic,
current: Self,
new: Self,
success: Ordering,
failure: Ordering,
) -> Result<Self, Self> {
atomic.compare_exchange(current, new, success, failure)
}
}
impl const Atomic for u32 {
type Atomic = AtomicU32;
fn new() -> Self::Atomic {
AtomicU32::new(0)
}
}
impl AtomicOp for u32 {
fn fetch_or(atomic: &Self::Atomic, val: Self, order: Ordering) -> Self {
atomic.fetch_or(val, order)
}
fn fetch_and(atomic: &Self::Atomic, val: Self, order: Ordering) -> Self {
atomic.fetch_and(val, order)
}
fn load(atomic: &Self::Atomic, order: Ordering) -> Self {
atomic.load(order)
}
fn store(atomic: &Self::Atomic, val: Self, order: Ordering) {
atomic.store(val, order)
}
fn compare_exchange(
atomic: &Self::Atomic,
current: Self,
new: Self,
success: Ordering,
failure: Ordering,
) -> Result<Self, Self> {
atomic.compare_exchange(current, new, success, failure)
}
}
impl const Atomic for u64 {
type Atomic = AtomicU64;
fn new() -> Self::Atomic {
AtomicU64::new(0)
}
}
impl AtomicOp for u64 {
fn fetch_or(atomic: &Self::Atomic, val: Self, order: Ordering) -> Self {
atomic.fetch_or(val, order)
}
fn fetch_and(atomic: &Self::Atomic, val: Self, order: Ordering) -> Self {
atomic.fetch_and(val, order)
}
fn load(atomic: &Self::Atomic, order: Ordering) -> Self {
atomic.load(order)
}
fn store(atomic: &Self::Atomic, val: Self, order: Ordering) {
atomic.store(val, order)
}
fn compare_exchange(
atomic: &Self::Atomic,
current: Self,
new: Self,
success: Ordering,
failure: Ordering,
) -> Result<Self, Self> {
atomic.compare_exchange(current, new, success, failure)
}
}
pub struct Flags<E: Discriminant>
where
E::Repr: Atomic + Into<usize> + TryFrom<usize>,
{
repr: <E::Repr as Atomic>::Atomic,
_phantom: PhantomData<E>,
}
impl<E: Discriminant> Default for Flags<E>
where
<E as sync::Discriminant>::Repr: Atomic + TryFrom<usize>,
<<E as sync::Discriminant>::Repr as Atomic>::Atomic: Default,
{
fn default() -> Self {
Self {
repr: Default::default(),
_phantom: Default::default(),
}
}
}
impl<E: Discriminant> Flags<E>
where
E::Repr: AtomicOp + Into<usize> + TryFrom<usize> + Copy,
{
pub fn new() -> Self {
Self {
repr: E::Repr::new(),
_phantom: PhantomData,
}
}
pub fn set(&self, variant: &E) {
let bit: usize = variant.discriminant().into();
let mask = E::Repr::try_from(1usize << bit)
.ok()
.expect("invalid discriminant conversion");
E::Repr::fetch_or(&self.repr, mask, Ordering::Release);
}
pub fn clear(&self, variant: &E) {
let bit: usize = variant.discriminant().into();
let mask = E::Repr::try_from(1usize << bit)
.ok()
.expect("invalid discriminant conversion");
E::Repr::fetch_and(&self.repr, mask, Ordering::Release);
}
pub fn is_set(&self, variant: &E) -> bool {
let bit: usize = variant.discriminant().into();
let mask = E::Repr::try_from(1usize << bit)
.ok()
.expect("invalid discriminant conversion");
let current = E::Repr::load(&self.repr, Ordering::Acquire);
let current_usize: usize = current.into();
let mask_usize: usize = mask.into();
current_usize & mask_usize != 0
}
pub fn clear_all(&self) {
E::Repr::fetch_and(
&self.repr,
E::Repr::try_from(0).ok().expect(""),
Ordering::Release,
);
}
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum Signal {
On,
Off,
}
#[repr(u8)]
#[derive(Clone, Copy)]
pub enum Closure {
Closed,
}
impl Discriminant for Closure {
type Repr = u8;
fn discriminant(&self) -> Self::Repr {
*self as u8
}
}
impl Discriminant for Signal {
type Repr = u8;
fn discriminant(&self) -> Self::Repr {
*self as u8
}
}
#[derive(Default)]
pub struct Waiter {
link: Link,
waker: WakerCell,
signal: Flags<Signal>,
}
impl Waiter {
pub fn from_waker(waker: Waker) -> Self {
let mut waiter = Self::default();
waiter.assign_waker(waker);
waiter
}
pub fn wake_by_ref(&self) {
self.waker.wake_by_ref();
}
pub fn assign_waker(&self, waker: Waker) {
self.waker.set(waker);
}
pub fn signaled(&self) -> bool {
self.signal.is_set(&Signal::On)
}
pub fn signal(&self) {
self.signal.set(&Signal::On);
}
pub fn reset(&mut self) {
self.link = Link::default();
self.signal = Default::default();
}
}
pub type PinnedWaiter = Pin<Box<Waiter>>;
pub type Waiters = Queue<Waiter>;
pub trait WaitersExt {
fn notify_one(&self);
fn notify_all(&self);
}
impl WaitersExt for Waiters {
fn notify_one(&self) {
if let Some(x) = unsafe { self.dequeue() } {
x.wake_by_ref();
}
}
fn notify_all(&self) {
while let Some(x) = unsafe { self.dequeue() } {
x.wake_by_ref();
}
}
}
pub struct AtomicWaker(AtomicPtr<Waker>);
pub struct Barrier {
count: AtomicUsize,
generation: AtomicUsize,
waiters: Waiters,
}
pub struct Semaphore {
permits: AtomicUsize,
waiters: Waiters,
}
#[repr(u8)]
#[derive(Clone, Copy, PartialEq)]
pub enum InitState {
Uninitialized = 0,
Initializing = 1,
Initialized = 2,
}
impl Discriminant for InitState {
type Repr = u8;
fn discriminant(&self) -> Self::Repr {
*self as u8
}
}