small fixes, std implies alloc, dropguarded wrapper with dropguard

This commit is contained in:
Janis 2025-07-03 16:50:20 +02:00
parent f23f815708
commit 4f1e4b1672
4 changed files with 69 additions and 3 deletions

View file

@ -6,7 +6,7 @@ edition = "2024"
[features]
default = ["alloc"]
alloc = []
std = []
std = ["alloc"]
nightly = []
[dependencies]

View file

@ -1,4 +1,8 @@
use core::{cell::UnsafeCell, mem::ManuallyDrop};
use core::{
cell::UnsafeCell,
mem::ManuallyDrop,
ops::{Deref, DerefMut},
};
/// A guard that runs a closure when it is dropped.
pub struct DropGuard<F: FnOnce()>(UnsafeCell<ManuallyDrop<F>>);
@ -10,6 +14,10 @@ where
pub fn new(f: F) -> DropGuard<F> {
Self(UnsafeCell::new(ManuallyDrop::new(f)))
}
pub fn guard<T>(self, t: T) -> DropGuarded<T, F> {
DropGuarded(t, self)
}
}
impl<F> Drop for DropGuard<F>
@ -32,3 +40,45 @@ where
DropGuard::new(f)
}
}
pub struct DropGuarded<T, F: FnOnce()>(T, DropGuard<F>);
impl<T, F> DropGuarded<T, F>
where
F: FnOnce(),
{
pub fn new(value: T, f: F) -> Self {
Self(value, DropGuard::new(f))
}
pub fn into_inner(self) -> T {
self.0
}
pub fn map<U, G>(self, f: G) -> DropGuarded<U, F>
where
G: FnOnce(T) -> U,
{
DropGuarded(f(self.0), self.1)
}
}
impl<T, F> Deref for DropGuarded<T, F>
where
F: FnOnce(),
{
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T, F> DerefMut for DropGuarded<T, F>
where
F: FnOnce(),
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

View file

@ -46,6 +46,8 @@ impl Lock {
}
pub fn unlock(&self) {
// use release semantics to ensure that all previous writes are
// available to other threads.
self.inner.fetch_and(!LOCKED_BIT, Ordering::Release);
}
@ -115,6 +117,16 @@ impl Lock {
state = self.inner.load(Ordering::Relaxed);
}
}
pub fn wait(&self) {
let state = self.inner.load(Ordering::Acquire);
atomic_wait::wait(&self.inner, state);
}
pub fn wake_one(&self) {
// Notify one thread waiting on this lock.
atomic_wait::wake_one(&self.inner);
}
}
pub struct SpinWait {

View file

@ -1,7 +1,8 @@
use core::ops::{Deref, DerefMut};
#[repr(transparent)]
pub struct Send<T>(pub(self) T);
#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Copy)]
pub struct Send<T>(pub T);
unsafe impl<T> core::marker::Send for Send<T> {}
@ -22,6 +23,9 @@ impl<T> Send<T> {
pub unsafe fn new(value: T) -> Self {
Self(value)
}
pub fn into_inner(self) -> T {
self.0
}
}
/// returns the number of available hardware threads, or 1 if it cannot be determined.