Skip to content

Add rustc_diagnostic_item to sys::Mutex methods #141690

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

Merged
merged 3 commits into from
May 29, 2025
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
3 changes: 3 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2071,6 +2071,9 @@ symbols! {
sym,
sync,
synthetic,
sys_mutex_lock,
sys_mutex_try_lock,
sys_mutex_unlock,
t32,
target,
target_abi,
Expand Down
6 changes: 6 additions & 0 deletions library/std/src/sys/sync/mutex/futex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ impl Mutex {
}

#[inline]
// Make this a diagnostic item for Miri's concurrency model checker.
#[cfg_attr(not(test), rustc_diagnostic_item = "sys_mutex_try_lock")]
pub fn try_lock(&self) -> bool {
self.futex.compare_exchange(UNLOCKED, LOCKED, Acquire, Relaxed).is_ok()
}

#[inline]
// Make this a diagnostic item for Miri's concurrency model checker.
#[cfg_attr(not(test), rustc_diagnostic_item = "sys_mutex_lock")]
pub fn lock(&self) {
if self.futex.compare_exchange(UNLOCKED, LOCKED, Acquire, Relaxed).is_err() {
self.lock_contended();
Expand Down Expand Up @@ -80,6 +84,8 @@ impl Mutex {
}

#[inline]
// Make this a diagnostic item for Miri's concurrency model checker.
#[cfg_attr(not(test), rustc_diagnostic_item = "sys_mutex_unlock")]
pub unsafe fn unlock(&self) {
if self.futex.swap(UNLOCKED, Release) == CONTENDED {
// We only wake up one thread. When that thread locks the mutex, it
Expand Down
8 changes: 7 additions & 1 deletion library/std/src/sys/sync/mutex/pthread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::sys::pal::sync as pal;
use crate::sys::sync::OnceBox;

pub struct Mutex {
pub pal: OnceBox<pal::Mutex>,
pub(in crate::sys::sync) pal: OnceBox<pal::Mutex>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed for Miri or just a pedantic change? Makes sense in either case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a pedantic change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To give more context -- the model checking for mutexes would become weird or even unsound if the mutex API is bypassed by directly accessing the underlying mutex operations, so we wanted to reduce the risk of that happening.

}

impl Mutex {
Expand All @@ -28,20 +28,26 @@ impl Mutex {
}

#[inline]
// Make this a diagnostic item for Miri's concurrency model checker.
#[cfg_attr(not(test), rustc_diagnostic_item = "sys_mutex_lock")]
pub fn lock(&self) {
// SAFETY: we call `init` above, therefore reentrant locking is safe.
// In `drop` we ensure that the mutex is not destroyed while locked.
unsafe { self.get().lock() }
}

#[inline]
// Make this a diagnostic item for Miri's concurrency model checker.
#[cfg_attr(not(test), rustc_diagnostic_item = "sys_mutex_unlock")]
pub unsafe fn unlock(&self) {
// SAFETY: the mutex can only be locked if it is already initialized
// and we observed this initialization since we observed the locking.
unsafe { self.pal.get_unchecked().unlock() }
}

#[inline]
// Make this a diagnostic item for Miri's concurrency model checker.
#[cfg_attr(not(test), rustc_diagnostic_item = "sys_mutex_try_lock")]
pub fn try_lock(&self) -> bool {
// SAFETY: we call `init` above, therefore reentrant locking is safe.
// In `drop` we ensure that the mutex is not destroyed while locked.
Expand Down
Loading