Skip to content

Commit b271f84

Browse files
committed
Move hardware lock elision support to a separate Cargo feature
1 parent 7b2f984 commit b271f84

5 files changed

Lines changed: 14 additions & 6 deletions

File tree

.github/workflows/rust.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ jobs:
2525
- channel: nightly
2626
feature: nightly
2727
os: ubuntu
28+
- channel: nightly
29+
feature: hardware-lock-elision
30+
os: ubuntu
2831

2932
steps:
3033
- uses: actions/checkout@v2

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ nightly = ["parking_lot_core/nightly", "lock_api/nightly"]
2828
deadlock_detection = ["parking_lot_core/deadlock_detection"]
2929
serde = ["lock_api/serde"]
3030
send_guard = []
31+
hardware-lock-elision = []
3132

3233
[workspace]
3334
exclude = ["benchmark"]

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ in the Rust standard library:
5050
library versions of those types.
5151
7. `RwLock` takes advantage of hardware lock elision on processors that
5252
support it, which can lead to huge performance wins with many readers.
53+
This must be enabled with the `hardware-lock-elision` feature.
5354
8. `RwLock` uses a task-fair locking policy, which avoids reader and writer
5455
starvation, whereas the standard library version makes no guarantees.
5556
9. `Condvar` is guaranteed not to produce spurious wakeups. A thread will
@@ -93,8 +94,6 @@ There are a few restrictions when using this library on stable Rust:
9394
- You will have to use the `const_*` functions (e.g. `const_mutex(val)`) to
9495
statically initialize the locking primitives. Using e.g. `Mutex::new(val)`
9596
does not work on stable Rust yet.
96-
- `RwLock` will not be able to take advantage of hardware lock elision for
97-
readers, which improves performance when there are multiple readers.
9897
- The `wasm32-unknown-unknown` target is only supported on nightly and requires
9998
`-C target-feature=+atomics` in `RUSTFLAGS`.
10099

@@ -126,6 +125,10 @@ To allow sending `MutexGuard`s and `RwLock*Guard`s to other threads, enable the
126125
Note that the `deadlock_detection` and `send_guard` features are incompatible
127126
and cannot be used together.
128127

128+
Hardware lock elision support for x86 can be enabled with the
129+
`hardware-lock-elision` feature. This requires Rust 1.59 due to the use of
130+
inline assembly.
131+
129132
The core parking lot API is provided by the `parking_lot_core` crate. It is
130133
separate from the synchronization primitives in the `parking_lot` crate so that
131134
changes to the core API do not cause breaking changes for users of `parking_lot`.

src/elision.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ pub trait AtomicElisionExt {
2626
#[inline]
2727
pub fn have_elision() -> bool {
2828
cfg!(all(
29-
feature = "nightly",
29+
feature = "hardware-lock-elision",
3030
any(target_arch = "x86", target_arch = "x86_64"),
3131
))
3232
}
3333

3434
// This implementation is never actually called because it is guarded by
3535
// have_elision().
36-
#[cfg(not(all(feature = "nightly", any(target_arch = "x86", target_arch = "x86_64"))))]
36+
#[cfg(not(all(feature = "hardware-lock-elision", any(target_arch = "x86", target_arch = "x86_64"))))]
3737
impl AtomicElisionExt for AtomicUsize {
3838
type IntType = usize;
3939

@@ -48,13 +48,14 @@ impl AtomicElisionExt for AtomicUsize {
4848
}
4949
}
5050

51-
#[cfg(all(feature = "nightly", any(target_arch = "x86", target_arch = "x86_64")))]
51+
#[cfg(all(feature = "hardware-lock-elision", any(target_arch = "x86", target_arch = "x86_64")))]
5252
impl AtomicElisionExt for AtomicUsize {
5353
type IntType = usize;
5454

5555
#[inline]
5656
fn elision_compare_exchange_acquire(&self, current: usize, new: usize) -> Result<usize, usize> {
5757
unsafe {
58+
use core::arch::asm;
5859
let prev: usize;
5960
#[cfg(target_pointer_width = "32")]
6061
asm!(
@@ -85,6 +86,7 @@ impl AtomicElisionExt for AtomicUsize {
8586
#[inline]
8687
fn elision_fetch_sub_release(&self, val: usize) -> usize {
8788
unsafe {
89+
use core::arch::asm;
8890
let prev: usize;
8991
#[cfg(target_pointer_width = "32")]
9092
asm!(

src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
1212
#![warn(missing_docs)]
1313
#![warn(rust_2018_idioms)]
14-
#![cfg_attr(feature = "nightly", feature(asm))]
1514

1615
mod condvar;
1716
mod elision;

0 commit comments

Comments
 (0)