Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(maitake-sync): add spin::RwLock #472

Merged
merged 4 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions maitake-sync/src/loom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,33 @@ mod inner {

#[cfg(test)]
pub(crate) mod thread {

pub(crate) use std::thread::{yield_now, JoinHandle};

pub(crate) fn spawn<F, T>(f: F) -> JoinHandle<T>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
use super::atomic::{AtomicUsize, Ordering::Relaxed};
thread_local! {
static CHILDREN: AtomicUsize = const { AtomicUsize::new(1) };
}

let track = super::alloc::track::Registry::current();
let subscriber = tracing::Dispatch::default();
let span = tracing::Span::current();
let num = CHILDREN.with(|children| children.fetch_add(1, Relaxed));
std::thread::spawn(move || {
let _tracing = tracing::dispatcher::set_default(&subscriber);
let _span = tracing::info_span!(parent: span, "thread", message = num).entered();

tracing::info!(num, "spawned child thread");
let _tracking = track.map(|track| track.set_default());
f()
let res = f();
tracing::info!(num, "child thread completed");

res
})
}
}
Expand All @@ -156,17 +173,26 @@ mod inner {
}

pub(crate) fn check(&self, f: impl FnOnce()) {
let _trace = crate::util::test::trace_init();
let _span = tracing::info_span!(
"test",
message = std::thread::current().name().unwrap_or("<unnamed>")
)
.entered();
let registry = super::alloc::track::Registry::default();
let _tracking = registry.set_default();

tracing::info!("started test...");
f();
tracing::info!("test completed successfully!");

registry.check();
}
}
}

#[cfg(test)]
pub(crate) fn model(f: impl FnOnce()) {
let _trace = crate::util::test::trace_init();
model::Builder::new().check(f)
}

Expand Down
4 changes: 4 additions & 0 deletions maitake-sync/src/spin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,21 @@
//! This module provides the following APIs:
//!
//! - [`Mutex`]: a synchronous [mutual exclusion] spinlock.
//! - [`RwLock`]: a synchronous [reader-writer] spinlock.
//! - [`InitOnce`]: a cell storing a [`MaybeUninit`](core::mem::MaybeUninit)
//! value which must be manually initialized prior to use.
//! - [`Lazy`]: an [`InitOnce`] cell coupled with an initializer function. The
//! [`Lazy`] cell ensures the initializer is called to initialize the
//! value the first time it is accessed.
//!
//! [mutual exclusion lock]: https://en.wikipedia.org/wiki/Mutual_exclusion
//! [reader-writer lock]: https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock
mod mutex;
pub mod once;
mod rwlock;

pub use self::{
mutex::*,
once::{InitOnce, Lazy},
rwlock::*,
};
Loading
Loading