From 2a458890bc398025623e7285f0c4dceaad4aca94 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 10 May 2022 14:17:34 +0200 Subject: [PATCH] weird things --- src/lib.rs | 1 + src/mutex.rs | 14 +++++++------- src/spsc.rs | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 src/spsc.rs diff --git a/src/lib.rs b/src/lib.rs index 68873ae..8ed3ef3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ mod linked_list; mod mutex; +mod spsc; diff --git a/src/mutex.rs b/src/mutex.rs index b9aeccc..d004fa4 100644 --- a/src/mutex.rs +++ b/src/mutex.rs @@ -13,7 +13,7 @@ struct Mutex { impl Mutex { pub fn new(value: T) -> Self { Self { - value, + value: UnsafeCell::new(value), status: AtomicU8::new(INIT), } } @@ -22,6 +22,7 @@ impl Mutex { if self .status .compare_exchange(INIT, ACQUIRED, Ordering::Acquire, Ordering::Relaxed) + .is_ok() { Some(MutexGuard { mutex: self }) } else { @@ -34,12 +35,11 @@ impl Mutex { // don't use spin loops // but I can't be bothered with the proper solution loop { - if self.status.compare_exchange_weak( - INIT, - ACQUIRED, - Ordering::Acquire, - Ordering::Relaxed, - ) { + if self + .status + .compare_exchange_weak(INIT, ACQUIRED, Ordering::Acquire, Ordering::Relaxed) + .is_ok() + { return MutexGuard { mutex: self }; } else { std::hint::spin_loop(); diff --git a/src/spsc.rs b/src/spsc.rs new file mode 100644 index 0000000..ab45c7b --- /dev/null +++ b/src/spsc.rs @@ -0,0 +1,35 @@ +use std::cell::UnsafeCell; +use std::mem::MaybeUninit; +use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; + +struct Spsc { + start: AtomicUsize, + end: AtomicUsize, + buffer: [UnsafeCell>; N], +} + +impl Spsc { + pub fn new() -> Self { + Self { + start: AtomicUsize::default(), + end: AtomicUsize::default(), + buffer: [UnsafeCell::new(MaybeUninit::uninit()); N], + } + } + + pub fn push(&self, value: T) { + let end = self.end.load(Ordering::Acquire); + let start = self.start.load(Ordering::Acquire); + + if end != 0 && end == start {}w + + if end < self.buffer.len() { + let end = unsafe { &self.buffer[end] }; + unsafe { end.get().write(value) }; + self.end.fetch_and(1, Ordering::Release); + } + } +} + +unsafe impl Sync for Spsc {} +unsafe impl Send for Spsc {}