-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Unbox mutexes and condvars on some platforms #77380
Unbox mutexes and condvars on some platforms #77380
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
…ex, r=dtolnay Split sys_common::Mutex in StaticMutex and MovableMutex. The (unsafe) `Mutex` from `sys_common` had a rather complicated interface. You were supposed to call `init()` manually, unless you could guarantee it was neither moved nor used reentrantly. Calling `destroy()` was also optional, although it was unclear if 1) resources might be leaked or not, and 2) if `destroy()` should only be called when `init()` was called. This allowed for a number of interesting (confusing?) different ways to use this `Mutex`, all captured in a single type. In practice, this type was only ever used in two ways: 1. As a static variable. In this case, neither `init()` nor `destroy()` are called. The variable is never moved, and it is never used reentrantly. It is only ever locked using the `LockGuard`, never with `raw_lock`. 2. As a `Box`ed variable. In this case, both `init()` and `destroy()` are called, it will be moved and possibly used reentrantly. No other combinations are used anywhere in `std`. This change simplifies things by splitting this `Mutex` type into two types matching the two use cases: `StaticMutex` and `MovableMutex`. The interface of both new types is now both safer and simpler. The first one does not call nor expose `init`/`destroy`, and the second one calls those automatically in its `new()` and `Drop` functions. Also, the locking functions of `MovableMutex` are no longer unsafe. --- This will also make it easier to conditionally box mutexes later, by moving that decision into sys/sys_common. Some of the mutex implementations (at least those of Wasm and 'sys/unsupported') are safe to move, so wouldn't need a box. ~~(But that's blocked on rust-lang#76932 for now.)~~ (See rust-lang#77380.)
…ex, r=dtolnay Split sys_common::Mutex in StaticMutex and MovableMutex. The (unsafe) `Mutex` from `sys_common` had a rather complicated interface. You were supposed to call `init()` manually, unless you could guarantee it was neither moved nor used reentrantly. Calling `destroy()` was also optional, although it was unclear if 1) resources might be leaked or not, and 2) if `destroy()` should only be called when `init()` was called. This allowed for a number of interesting (confusing?) different ways to use this `Mutex`, all captured in a single type. In practice, this type was only ever used in two ways: 1. As a static variable. In this case, neither `init()` nor `destroy()` are called. The variable is never moved, and it is never used reentrantly. It is only ever locked using the `LockGuard`, never with `raw_lock`. 2. As a `Box`ed variable. In this case, both `init()` and `destroy()` are called, it will be moved and possibly used reentrantly. No other combinations are used anywhere in `std`. This change simplifies things by splitting this `Mutex` type into two types matching the two use cases: `StaticMutex` and `MovableMutex`. The interface of both new types is now both safer and simpler. The first one does not call nor expose `init`/`destroy`, and the second one calls those automatically in its `new()` and `Drop` functions. Also, the locking functions of `MovableMutex` are no longer unsafe. --- This will also make it easier to conditionally box mutexes later, by moving that decision into sys/sys_common. Some of the mutex implementations (at least those of Wasm and 'sys/unsupported') are safe to move, so wouldn't need a box. ~~(But that's blocked on rust-lang#76932 for now.)~~ (See rust-lang#77380.)
☔ The latest upstream changes (presumably #77436) made this pull request unmergeable. Please resolve the merge conflicts. Note that reviewers usually do not review pull requests until merge conflicts are resolved! Once you resolve the conflicts, you should change the labels applied by bors to indicate that your PR is ready for review. Post this as a comment to change the labels:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r=me on the diff from #77147 to this (74237e9...dc67bde).
This commit keeps all mutexes boxed on all platforms, but makes it trivial to remove the box on some platforms later.
Cloudabi mutexes may be moved safely.
These mutexes are just a bool (in a cell), so can be moved without problems.
These mutexes are just an AtomicUsize, so can be moved without problems.
Windows SRW locks are movable (while not borrowed) according to their documentation.
This commit keeps all condvars boxed on all platforms, but makes it trivial to remove the box on some platforms later.
Cloudabi condvars may be moved safely.
These condvars are unsupported and implemented as a ZST, so can be moved without problems.
These condvars are just an AtomicUsize, so can be moved without problems.
Windows condition variables are movable (while not borrowed) according to their documentation.
Condvars are no longer guaranteed to panic in this case on all platforms. At least the unix implementation still does.
dc67bde
to
b1ce7a3
Compare
Thanks! Rebased to include #77147. |
@bors r+ |
📌 Commit b1ce7a3 has been approved by |
Thanks! Might be good to mark this as rollup=never, considering this changes platform-specific things. ^^ |
@bors rollup=iffy |
⌛ Testing commit b1ce7a3 with merge 84e18dd511d49cc9dcb9a3e2b6fefb7eed27be77... |
💥 Test timed out |
This seems unrelated. The tests passed on all platforms except the |
@bors retry |
☀️ Test successful - checks-actions, checks-azure |
@m-ou-se do you have any guidance for target maintainers that may want to get rid of the box? |
@jethrogb The reason for the |
Multiple improvements to RwLocks This PR replicates rust-lang#77147, rust-lang#77380 and rust-lang#84650 on RWLocks : - Split `sys_common::RWLock` in `StaticRWLock` and `MovableRWLock` - Unbox rwlocks on some platforms (Windows, Wasm and unsupported) - Simplify `RwLock::into_inner` Notes to reviewers : - For each target, I copied `MovableMutex` to guess if `MovableRWLock` should be boxed. - ~A comment says that `StaticMutex` is not re-entrant, I don't understand why and I don't know whether it applies to `StaticRWLock`.~ r? `@m-ou-se`
Make {Mutex, Condvar, RwLock}::new() const. This makes it possible to have `static M: Mutex<_> = Mutex::new(..);` 🎉 Our implementations [on Linux](rust-lang#95035), [on Windows](rust-lang#77380), and various BSDs and some tier 3 platforms have already been using a non-allocating const-constructible implementation. As of rust-lang#97647, the remaining platforms (most notably macOS) now have a const-constructible implementation as well. This means we can finally make these functions publicly const. Tracking issue: rust-lang#93740
Make {Mutex, Condvar, RwLock}::new() const. This makes it possible to have `static M: Mutex<_> = Mutex::new(..);` 🎉 Our implementations [on Linux](rust-lang/rust#95035), [on Windows](rust-lang/rust#77380), and various BSDs and some tier 3 platforms have already been using a non-allocating const-constructible implementation. As of rust-lang/rust#97647, the remaining platforms (most notably macOS) now have a const-constructible implementation as well. This means we can finally make these functions publicly const. Tracking issue: rust-lang/rust#93740
Both mutexes and condition variables contained a Box containing the actual os-specific object. This was done because moving these objects may cause undefined behaviour on some platforms.
However, this is not needed on Windows[1], Wasm[2], cloudabi[2], and 'unsupported'[3], were the box was only needlessly making them less efficient.
This change gets rid of the box on those platforms.
On those platforms,
Condvar
can no longer verify it is only used with oneMutex
, as mutexes no longer have a stable address. This was addressed and considered acceptable in #76932.[1]: https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initializesrwlock
[2]: These are just a single atomic integer together with futex wait/wake calls/instructions.
[3]: The
unsupported
platform doesn't support multiple threads at all.