mirror of
https://github.com/Noratrieb/nuclear.git
synced 2026-01-14 15:55:02 +01:00
weird things
This commit is contained in:
parent
1a76116ed0
commit
2a458890bc
3 changed files with 43 additions and 7 deletions
|
|
@ -1,2 +1,3 @@
|
||||||
mod linked_list;
|
mod linked_list;
|
||||||
mod mutex;
|
mod mutex;
|
||||||
|
mod spsc;
|
||||||
|
|
|
||||||
14
src/mutex.rs
14
src/mutex.rs
|
|
@ -13,7 +13,7 @@ struct Mutex<T> {
|
||||||
impl<T> Mutex<T> {
|
impl<T> Mutex<T> {
|
||||||
pub fn new(value: T) -> Self {
|
pub fn new(value: T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
value,
|
value: UnsafeCell::new(value),
|
||||||
status: AtomicU8::new(INIT),
|
status: AtomicU8::new(INIT),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -22,6 +22,7 @@ impl<T> Mutex<T> {
|
||||||
if self
|
if self
|
||||||
.status
|
.status
|
||||||
.compare_exchange(INIT, ACQUIRED, Ordering::Acquire, Ordering::Relaxed)
|
.compare_exchange(INIT, ACQUIRED, Ordering::Acquire, Ordering::Relaxed)
|
||||||
|
.is_ok()
|
||||||
{
|
{
|
||||||
Some(MutexGuard { mutex: self })
|
Some(MutexGuard { mutex: self })
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -34,12 +35,11 @@ impl<T> Mutex<T> {
|
||||||
// don't use spin loops
|
// don't use spin loops
|
||||||
// but I can't be bothered with the proper solution
|
// but I can't be bothered with the proper solution
|
||||||
loop {
|
loop {
|
||||||
if self.status.compare_exchange_weak(
|
if self
|
||||||
INIT,
|
.status
|
||||||
ACQUIRED,
|
.compare_exchange_weak(INIT, ACQUIRED, Ordering::Acquire, Ordering::Relaxed)
|
||||||
Ordering::Acquire,
|
.is_ok()
|
||||||
Ordering::Relaxed,
|
{
|
||||||
) {
|
|
||||||
return MutexGuard { mutex: self };
|
return MutexGuard { mutex: self };
|
||||||
} else {
|
} else {
|
||||||
std::hint::spin_loop();
|
std::hint::spin_loop();
|
||||||
|
|
|
||||||
35
src/spsc.rs
Normal file
35
src/spsc.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
|
use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
|
||||||
|
|
||||||
|
struct Spsc<const N: usize, T> {
|
||||||
|
start: AtomicUsize,
|
||||||
|
end: AtomicUsize,
|
||||||
|
buffer: [UnsafeCell<MaybeUninit<T>>; N],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize, T> Spsc<N, T> {
|
||||||
|
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<const N: usize, T> Sync for Spsc<N, T> {}
|
||||||
|
unsafe impl<const N: usize, T> Send for Spsc<N, T> {}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue