diff options
author | Jeff Vander Stoep <jeffv@google.com> | 2020-10-22 13:20:30 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-10-22 13:20:30 +0000 |
commit | eba4ddfc443fa4bdfe50b83200fdd03737fe7d2c (patch) | |
tree | a48ad005e42b21ab86e7c73beab3c96723e033d3 | |
parent | 57abb49346a58c2e5e1d8eccd7841b3b24e4ae4d (diff) | |
parent | 731465dfaac9b0862e470edc03335aeb539366de (diff) | |
download | parking_lot-eba4ddfc443fa4bdfe50b83200fdd03737fe7d2c.tar.gz |
Upgrade parking_lot to version 0.11.0 am: 16823f4fe5 am: e0ea34f637 am: 0443fdcd81 am: 731465dfaa
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/parking_lot/+/1470183
Change-Id: I62731e5abee2c6274ec7420b237acd8ff6633355
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 6 | ||||
-rw-r--r-- | CHANGELOG.md | 14 | ||||
-rw-r--r-- | Cargo.toml | 16 | ||||
-rw-r--r-- | Cargo.toml.orig | 14 | ||||
-rw-r--r-- | METADATA | 6 | ||||
-rw-r--r-- | README.md | 17 | ||||
-rw-r--r-- | appveyor.yml | 59 | ||||
-rw-r--r-- | bors.toml | 3 | ||||
-rw-r--r-- | src/condvar.rs | 6 | ||||
-rw-r--r-- | src/lib.rs | 9 | ||||
-rw-r--r-- | src/mutex.rs | 8 | ||||
-rw-r--r-- | src/raw_fair_mutex.rs | 11 | ||||
-rw-r--r-- | src/raw_mutex.rs | 22 | ||||
-rw-r--r-- | src/raw_rwlock.rs | 47 | ||||
-rw-r--r-- | src/rwlock.rs | 8 | ||||
-rw-r--r-- | src/util.rs | 3 |
17 files changed, 130 insertions, 121 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 1ac0ea4..ef88cf4 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "4cb93a3268fcf79c823a3d860047e3e88c626b51" + "sha1": "8c154bedcb392b87feea9b29054f3f0cabcd6a28" } } @@ -10,6 +10,7 @@ rust_library { "default", ], rustlibs: [ + "libinstant", "liblock_api", "libparking_lot_core", ], @@ -17,8 +18,9 @@ rust_library { // dependent_library ["feature_list"] // cfg-if-0.1.10 +// instant-0.1.7 // libc-0.2.79 "default,std" -// lock_api-0.3.4 -// parking_lot_core-0.7.2 +// lock_api-0.4.1 +// parking_lot_core-0.8.0 // scopeguard-1.1.0 // smallvec-1.4.2 diff --git a/CHANGELOG.md b/CHANGELOG.md index c187e4d..661a49a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +## parking_lot 0.11.0, parking_lot_core 0.8.0, lock_api 0.4.0 (2020-06-23) + +- Add `is_locked` method to mutex types. (#235) +- Make `RawReentrantMutex` public. (#233) +- Allow lock guard to be sent to another thread with the `send_guard` feature. (#240) +- Use `Instant` type from the `instant` crate on wasm32-unknown-unknown. (#231) +- Remove deprecated and unsound `MappedRwLockWriteGuard::downgrade`. (#244) +- Most methods on the `Raw*` traits have been made unsafe since they assume + the current thread holds the lock. (#243) + +## parking_lot_core 0.7.2 (2020-04-21) + +- Add support for `wasm32-unknown-unknown` under the "nightly" feature. (#226) + ## parking_lot 0.10.2 (2020-04-10) - Update minimum version of `lock_api`. @@ -13,7 +13,7 @@ [package] edition = "2018" name = "parking_lot" -version = "0.10.2" +version = "0.11.0" authors = ["Amanieu d'Antras <amanieu@gmail.com>"] description = "More compact and efficient implementations of the standard synchronization primitives." readme = "README.md" @@ -21,20 +21,26 @@ keywords = ["mutex", "condvar", "rwlock", "once", "thread"] categories = ["concurrency"] license = "Apache-2.0/MIT" repository = "https://github.com/Amanieu/parking_lot" +[dependencies.instant] +version = "0.1.4" + [dependencies.lock_api] -version = "0.3.4" +version = "0.4.0" [dependencies.parking_lot_core] -version = "0.7.1" +version = "0.8.0" [dev-dependencies.bincode] -version = "1.1.3" +version = "1.3.0" [dev-dependencies.rand] -version = "0.7" +version = "0.7.3" [features] deadlock_detection = ["parking_lot_core/deadlock_detection"] default = [] nightly = ["parking_lot_core/nightly", "lock_api/nightly"] owning_ref = ["lock_api/owning_ref"] +send_guard = [] serde = ["lock_api/serde"] +stdweb = ["instant/stdweb"] +wasm-bindgen = ["instant/wasm-bindgen"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index ebe62d5..1564fa4 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,6 +1,6 @@ [package] name = "parking_lot" -version = "0.10.2" +version = "0.11.0" authors = ["Amanieu d'Antras <amanieu@gmail.com>"] description = "More compact and efficient implementations of the standard synchronization primitives." license = "Apache-2.0/MIT" @@ -11,14 +11,15 @@ categories = ["concurrency"] edition = "2018" [dependencies] -parking_lot_core = { path = "core", version = "0.7.1" } -lock_api = { path = "lock_api", version = "0.3.4" } +parking_lot_core = { path = "core", version = "0.8.0" } +lock_api = { path = "lock_api", version = "0.4.0" } +instant = "0.1.4" [dev-dependencies] -rand = "0.7" +rand = "0.7.3" # Used when testing out serde support. -bincode = {version = "1.1.3"} +bincode = "1.3.0" [features] default = [] @@ -26,6 +27,9 @@ owning_ref = ["lock_api/owning_ref"] nightly = ["parking_lot_core/nightly", "lock_api/nightly"] deadlock_detection = ["parking_lot_core/deadlock_detection"] serde = ["lock_api/serde"] +stdweb = ["instant/stdweb"] +wasm-bindgen = ["instant/wasm-bindgen"] +send_guard = [] [workspace] exclude = ["benchmark"] @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/parking_lot/parking_lot-0.10.2.crate" + value: "https://static.crates.io/crates/parking_lot/parking_lot-0.11.0.crate" } - version: "0.10.2" + version: "0.11.0" license_type: NOTICE last_upgrade_date { year: 2020 month: 10 - day: 14 + day: 20 } } @@ -1,7 +1,8 @@ parking_lot ============ -[![Build Status](https://travis-ci.org/Amanieu/parking_lot.svg?branch=master)](https://travis-ci.org/Amanieu/parking_lot) [![Build status](https://ci.appveyor.com/api/projects/status/wppcc32ttpud0a30/branch/master?svg=true)](https://ci.appveyor.com/project/Amanieu/parking-lot/branch/master) [![Crates.io](https://img.shields.io/crates/v/parking_lot.svg)](https://crates.io/crates/parking_lot) +![Rust](https://github.com/Amanieu/parking_lot/workflows/Rust/badge.svg) +[![Crates.io](https://img.shields.io/crates/v/parking_lot.svg)](https://crates.io/crates/parking_lot) [Documentation (synchronization primitives)](https://docs.rs/parking_lot/) @@ -71,6 +72,8 @@ in the Rust standard library: 18. Optional support for [serde](https://docs.serde.rs/serde/). Enable via the feature `serde`. **NOTE!** this support is for `Mutex`, `ReentrantMutex`, and `RwLock` only; `Condvar` and `Once` are not currently supported. +19. Lock guards can be sent to other threads when the `send_guard` feature is + enabled. ## The parking lot @@ -92,6 +95,8 @@ There are a few restrictions when using this library on stable Rust: does not work on stable Rust yet. - `RwLock` will not be able to take advantage of hardware lock elision for readers, which improves performance when there are multiple readers. +- The `wasm32-unknown-unknown` target is only supported on nightly and requires + `-C target-feature=+atomics` in `RUSTFLAGS`. To enable nightly-only functionality, you need to enable the `nightly` feature in Cargo (see below). @@ -102,19 +107,25 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -parking_lot = "0.10" +parking_lot = "0.11" ``` To enable nightly-only features, add this to your `Cargo.toml` instead: ```toml [dependencies] -parking_lot = { version = "0.10", features = ["nightly"] } +parking_lot = { version = "0.11", features = ["nightly"] } ``` The experimental deadlock detector can be enabled with the `deadlock_detection` Cargo feature. +To allow sending `MutexGuard`s and `RwLock*Guard`s to other threads, enable the +`send_guard` option. + +Note that the `deadlock_detection` and `send_guard` features are incompatible +and cannot be used together. + The core parking lot API is provided by the `parking_lot_core` crate. It is separate from the synchronization primitives in the `parking_lot` crate so that changes to the core API do not cause breaking changes for users of `parking_lot`. diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index a7eb5cf..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,59 +0,0 @@ -environment: - TRAVIS_CARGO_NIGHTLY_FEATURE: nightly - RUST_TEST_THREADS: 1 - matrix: - - TARGET: x86_64-pc-windows-msvc - MSYSTEM: MINGW64 - CPU: x86_64 - TOOLCHAIN: nightly - FEATURES: nightly - - TARGET: i686-pc-windows-msvc - MSYSTEM: MINGW32 - CPU: i686 - TOOLCHAIN: nightly - FEATURES: nightly - - TARGET: x86_64-pc-windows-gnu - MSYSTEM: MINGW64 - CPU: x86_64 - TOOLCHAIN: nightly - FEATURES: nightly - - TARGET: i686-pc-windows-gnu - MSYSTEM: MINGW32 - CPU: i686 - TOOLCHAIN: nightly - FEATURES: nightly - - TARGET: x86_64-pc-windows-msvc - MSYSTEM: MINGW64 - CPU: x86_64 - TOOLCHAIN: 1.36.0 - - TARGET: i686-pc-windows-msvc - MSYSTEM: MINGW32 - CPU: i686 - TOOLCHAIN: 1.36.0 - - TARGET: x86_64-pc-windows-gnu - MSYSTEM: MINGW64 - CPU: x86_64 - TOOLCHAIN: 1.36.0 - - TARGET: i686-pc-windows-gnu - MSYSTEM: MINGW32 - CPU: i686 - TOOLCHAIN: 1.36.0 - -install: - - set PATH=C:\msys64\%MSYSTEM%\bin;c:\msys64\usr\bin;%PATH% - - pacman --noconfirm -Syu mingw-w64-%CPU%-make - - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe - - rustup-init.exe -y --default-host %TARGET% --default-toolchain %TOOLCHAIN% - - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - - rustc -vV - - cargo -vV - -build_script: - - cargo build --features "%FEATURES%" - -test_script: - - cargo test --all --features "%FEATURES%" - - cargo doc --all - - cd benchmark - - cargo run --release --bin mutex -- 2 1 0 1 2 - - cargo run --release --bin rwlock -- 1 1 1 0 1 2 @@ -1,3 +1,4 @@ status = [ - "continuous-integration/travis-ci/push", + "build_tier_one", + "build_other_platforms", ] diff --git a/src/condvar.rs b/src/condvar.rs index 0afda3a..5451168 100644 --- a/src/condvar.rs +++ b/src/condvar.rs @@ -12,9 +12,10 @@ use core::{ fmt, ptr, sync::atomic::{AtomicPtr, Ordering}, }; +use instant::Instant; use lock_api::RawMutex as RawMutex_; use parking_lot_core::{self, ParkResult, RequeueOp, UnparkResult, DEFAULT_PARK_TOKEN}; -use std::time::{Duration, Instant}; +use std::time::Duration; /// A type indicating whether a timed wait on a condition variable returned /// due to a time out or not. @@ -413,10 +414,11 @@ impl fmt::Debug for Condvar { #[cfg(test)] mod tests { use crate::{Condvar, Mutex, MutexGuard}; + use instant::Instant; use std::sync::mpsc::channel; use std::sync::Arc; use std::thread; - use std::time::{Duration, Instant}; + use std::time::Duration; #[test] fn smoke() { @@ -30,6 +30,15 @@ pub mod deadlock; #[cfg(not(feature = "deadlock_detection"))] mod deadlock; +// If deadlock detection is enabled, we cannot allow lock guards to be sent to +// other threads. +#[cfg(all(feature = "send_guard", feature = "deadlock_detection"))] +compile_error!("the `send_guard` and `deadlock_detection` features cannot be used together"); +#[cfg(feature = "send_guard")] +type GuardMarker = lock_api::GuardSend; +#[cfg(not(feature = "send_guard"))] +type GuardMarker = lock_api::GuardNoSend; + pub use self::condvar::{Condvar, WaitTimeoutResult}; pub use self::fair_mutex::{const_fair_mutex, FairMutex, FairMutexGuard, MappedFairMutexGuard}; pub use self::mutex::{const_mutex, MappedMutexGuard, Mutex, MutexGuard}; diff --git a/src/mutex.rs b/src/mutex.rs index 36e5ea7..9f63cb9 100644 --- a/src/mutex.rs +++ b/src/mutex.rs @@ -21,18 +21,18 @@ use lock_api; /// /// A typical unfair lock can often end up in a situation where a single thread /// quickly acquires and releases the same mutex in succession, which can starve -/// other threads waiting to acquire the mutex. While this improves performance +/// other threads waiting to acquire the mutex. While this improves throughput /// because it doesn't force a context switch when a thread tries to re-acquire /// a mutex it has just released, this can starve other threads. /// /// This mutex uses [eventual fairness](https://trac.webkit.org/changeset/203350) /// to ensure that the lock will be fair on average without sacrificing -/// performance. This is done by forcing a fair unlock on average every 0.5ms, +/// throughput. This is done by forcing a fair unlock on average every 0.5ms, /// which will force the lock to go to the next thread waiting for the mutex. /// /// Additionally, any critical section longer than 1ms will always use a fair -/// unlock, which has a negligible performance impact compared to the length of -/// the critical section. +/// unlock, which has a negligible impact on throughput considering the length +/// of the critical section. /// /// You can also force a fair unlock by calling `MutexGuard::unlock_fair` when /// unlocking a mutex instead of simply dropping the `MutexGuard`. diff --git a/src/raw_fair_mutex.rs b/src/raw_fair_mutex.rs index 3eb7ddb..0da6828 100644 --- a/src/raw_fair_mutex.rs +++ b/src/raw_fair_mutex.rs @@ -27,19 +27,24 @@ unsafe impl lock_api::RawMutex for RawFairMutex { } #[inline] - fn unlock(&self) { + unsafe fn unlock(&self) { self.unlock_fair() } + + #[inline] + fn is_locked(&self) -> bool { + self.0.is_locked() + } } unsafe impl lock_api::RawMutexFair for RawFairMutex { #[inline] - fn unlock_fair(&self) { + unsafe fn unlock_fair(&self) { self.0.unlock_fair() } #[inline] - fn bump(&self) { + unsafe fn bump(&self) { self.0.bump() } } diff --git a/src/raw_mutex.rs b/src/raw_mutex.rs index ee39c3b..06667d3 100644 --- a/src/raw_mutex.rs +++ b/src/raw_mutex.rs @@ -10,9 +10,9 @@ use core::{ sync::atomic::{AtomicU8, Ordering}, time::Duration, }; -use lock_api::{GuardNoSend, RawMutex as RawMutex_}; +use instant::Instant; +use lock_api::RawMutex as RawMutex_; use parking_lot_core::{self, ParkResult, SpinWait, UnparkResult, UnparkToken, DEFAULT_PARK_TOKEN}; -use std::time::Instant; // UnparkToken used to indicate that that the target thread should attempt to // lock the mutex again as soon as it is unparked. @@ -60,7 +60,7 @@ unsafe impl lock_api::RawMutex for RawMutex { state: AtomicU8::new(0), }; - type GuardMarker = GuardNoSend; + type GuardMarker = crate::GuardMarker; #[inline] fn lock(&self) { @@ -97,8 +97,8 @@ unsafe impl lock_api::RawMutex for RawMutex { } #[inline] - fn unlock(&self) { - unsafe { deadlock::release_resource(self as *const _ as usize) }; + unsafe fn unlock(&self) { + deadlock::release_resource(self as *const _ as usize); if self .state .compare_exchange(LOCKED_BIT, 0, Ordering::Release, Ordering::Relaxed) @@ -108,12 +108,18 @@ unsafe impl lock_api::RawMutex for RawMutex { } self.unlock_slow(false); } + + #[inline] + fn is_locked(&self) -> bool { + let state = self.state.load(Ordering::Relaxed); + state & LOCKED_BIT != 0 + } } unsafe impl lock_api::RawMutexFair for RawMutex { #[inline] - fn unlock_fair(&self) { - unsafe { deadlock::release_resource(self as *const _ as usize) }; + unsafe fn unlock_fair(&self) { + deadlock::release_resource(self as *const _ as usize); if self .state .compare_exchange(LOCKED_BIT, 0, Ordering::Release, Ordering::Relaxed) @@ -125,7 +131,7 @@ unsafe impl lock_api::RawMutexFair for RawMutex { } #[inline] - fn bump(&self) { + unsafe fn bump(&self) { if self.state.load(Ordering::Relaxed) & PARKED_BIT != 0 { self.bump_slow(); } diff --git a/src/raw_rwlock.rs b/src/raw_rwlock.rs index 8c1ad11..1feb0bd 100644 --- a/src/raw_rwlock.rs +++ b/src/raw_rwlock.rs @@ -12,11 +12,12 @@ use core::{ cell::Cell, sync::atomic::{AtomicUsize, Ordering}, }; -use lock_api::{GuardNoSend, RawRwLock as RawRwLock_, RawRwLockUpgrade}; +use instant::Instant; +use lock_api::{RawRwLock as RawRwLock_, RawRwLockUpgrade}; use parking_lot_core::{ self, deadlock, FilterOp, ParkResult, ParkToken, SpinWait, UnparkResult, UnparkToken, }; -use std::time::{Duration, Instant}; +use std::time::Duration; // This reader-writer lock implementation is based on Boost's upgrade_mutex: // https://github.com/boostorg/thread/blob/fc08c1fe2840baeeee143440fba31ef9e9a813c8/include/boost/thread/v2/shared_mutex.hpp#L432 @@ -61,7 +62,7 @@ unsafe impl lock_api::RawRwLock for RawRwLock { state: AtomicUsize::new(0), }; - type GuardMarker = GuardNoSend; + type GuardMarker = crate::GuardMarker; #[inline] fn lock_exclusive(&self) { @@ -91,7 +92,7 @@ unsafe impl lock_api::RawRwLock for RawRwLock { } #[inline] - fn unlock_exclusive(&self) { + unsafe fn unlock_exclusive(&self) { self.deadlock_release(); if self .state @@ -126,7 +127,7 @@ unsafe impl lock_api::RawRwLock for RawRwLock { } #[inline] - fn unlock_shared(&self) { + unsafe fn unlock_shared(&self) { self.deadlock_release(); let state = if have_elision() { self.state.elision_fetch_sub_release(ONE_READER) @@ -137,17 +138,23 @@ unsafe impl lock_api::RawRwLock for RawRwLock { self.unlock_shared_slow(); } } + + #[inline] + fn is_locked(&self) -> bool { + let state = self.state.load(Ordering::Relaxed); + state & (WRITER_BIT | READERS_MASK) != 0 + } } unsafe impl lock_api::RawRwLockFair for RawRwLock { #[inline] - fn unlock_shared_fair(&self) { + unsafe fn unlock_shared_fair(&self) { // Shared unlocking is always fair in this implementation. self.unlock_shared(); } #[inline] - fn unlock_exclusive_fair(&self) { + unsafe fn unlock_exclusive_fair(&self) { self.deadlock_release(); if self .state @@ -160,7 +167,7 @@ unsafe impl lock_api::RawRwLockFair for RawRwLock { } #[inline] - fn bump_shared(&self) { + unsafe fn bump_shared(&self) { if self.state.load(Ordering::Relaxed) & (READERS_MASK | WRITER_BIT) == ONE_READER | WRITER_BIT { @@ -169,7 +176,7 @@ unsafe impl lock_api::RawRwLockFair for RawRwLock { } #[inline] - fn bump_exclusive(&self) { + unsafe fn bump_exclusive(&self) { if self.state.load(Ordering::Relaxed) & PARKED_BIT != 0 { self.bump_exclusive_slow(); } @@ -178,7 +185,7 @@ unsafe impl lock_api::RawRwLockFair for RawRwLock { unsafe impl lock_api::RawRwLockDowngrade for RawRwLock { #[inline] - fn downgrade(&self) { + unsafe fn downgrade(&self) { let state = self .state .fetch_add(ONE_READER - WRITER_BIT, Ordering::Release); @@ -331,7 +338,7 @@ unsafe impl lock_api::RawRwLockUpgrade for RawRwLock { } #[inline] - fn unlock_upgradable(&self) { + unsafe fn unlock_upgradable(&self) { self.deadlock_release(); let state = self.state.load(Ordering::Relaxed); if state & PARKED_BIT == 0 { @@ -352,7 +359,7 @@ unsafe impl lock_api::RawRwLockUpgrade for RawRwLock { } #[inline] - fn upgrade(&self) { + unsafe fn upgrade(&self) { let state = self.state.fetch_sub( (ONE_READER | UPGRADABLE_BIT) - WRITER_BIT, Ordering::Relaxed, @@ -364,7 +371,7 @@ unsafe impl lock_api::RawRwLockUpgrade for RawRwLock { } #[inline] - fn try_upgrade(&self) -> bool { + unsafe fn try_upgrade(&self) -> bool { if self .state .compare_exchange_weak( @@ -384,7 +391,7 @@ unsafe impl lock_api::RawRwLockUpgrade for RawRwLock { unsafe impl lock_api::RawRwLockUpgradeFair for RawRwLock { #[inline] - fn unlock_upgradable_fair(&self) { + unsafe fn unlock_upgradable_fair(&self) { self.deadlock_release(); let state = self.state.load(Ordering::Relaxed); if state & PARKED_BIT == 0 { @@ -405,7 +412,7 @@ unsafe impl lock_api::RawRwLockUpgradeFair for RawRwLock { } #[inline] - fn bump_upgradable(&self) { + unsafe fn bump_upgradable(&self) { if self.state.load(Ordering::Relaxed) == ONE_READER | UPGRADABLE_BIT | PARKED_BIT { self.bump_upgradable_slow(); } @@ -414,7 +421,7 @@ unsafe impl lock_api::RawRwLockUpgradeFair for RawRwLock { unsafe impl lock_api::RawRwLockUpgradeDowngrade for RawRwLock { #[inline] - fn downgrade_upgradable(&self) { + unsafe fn downgrade_upgradable(&self) { let state = self.state.fetch_sub(UPGRADABLE_BIT, Ordering::Relaxed); // Wake up parked upgradable threads if there are any @@ -424,7 +431,7 @@ unsafe impl lock_api::RawRwLockUpgradeDowngrade for RawRwLock { } #[inline] - fn downgrade_to_upgradable(&self) { + unsafe fn downgrade_to_upgradable(&self) { let state = self.state.fetch_add( (ONE_READER | UPGRADABLE_BIT) - WRITER_BIT, Ordering::Release, @@ -465,7 +472,7 @@ unsafe impl lock_api::RawRwLockUpgradeTimed for RawRwLock { } #[inline] - fn try_upgrade_until(&self, timeout: Instant) -> bool { + unsafe fn try_upgrade_until(&self, timeout: Instant) -> bool { let state = self.state.fetch_sub( (ONE_READER | UPGRADABLE_BIT) - WRITER_BIT, Ordering::Relaxed, @@ -478,7 +485,7 @@ unsafe impl lock_api::RawRwLockUpgradeTimed for RawRwLock { } #[inline] - fn try_upgrade_for(&self, timeout: Duration) -> bool { + unsafe fn try_upgrade_for(&self, timeout: Duration) -> bool { let state = self.state.fetch_sub( (ONE_READER | UPGRADABLE_BIT) - WRITER_BIT, Ordering::Relaxed, @@ -892,7 +899,7 @@ impl RawRwLock { } #[cold] - fn bump_shared_slow(&self) { + unsafe fn bump_shared_slow(&self) { self.unlock_shared(); self.lock_shared(); } diff --git a/src/rwlock.rs b/src/rwlock.rs index 0381316..89987c6 100644 --- a/src/rwlock.rs +++ b/src/rwlock.rs @@ -31,18 +31,18 @@ use lock_api; /// /// A typical unfair lock can often end up in a situation where a single thread /// quickly acquires and releases the same lock in succession, which can starve -/// other threads waiting to acquire the rwlock. While this improves performance +/// other threads waiting to acquire the rwlock. While this improves throughput /// because it doesn't force a context switch when a thread tries to re-acquire /// a rwlock it has just released, this can starve other threads. /// /// This rwlock uses [eventual fairness](https://trac.webkit.org/changeset/203350) /// to ensure that the lock will be fair on average without sacrificing -/// performance. This is done by forcing a fair unlock on average every 0.5ms, +/// throughput. This is done by forcing a fair unlock on average every 0.5ms, /// which will force the lock to go to the next thread waiting for the rwlock. /// /// Additionally, any critical section longer than 1ms will always use a fair -/// unlock, which has a negligible performance impact compared to the length of -/// the critical section. +/// unlock, which has a negligible impact on throughput considering the length +/// of the critical section. /// /// You can also force a fair unlock by calling `RwLockReadGuard::unlock_fair` /// or `RwLockWriteGuard::unlock_fair` when unlocking a mutex instead of simply diff --git a/src/util.rs b/src/util.rs index c5496fc..19cc2c2 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,7 +5,8 @@ // http://opensource.org/licenses/MIT>, at your option. This file may not be // copied, modified, or distributed except according to those terms. -use std::time::{Duration, Instant}; +use instant::Instant; +use std::time::Duration; // Option::unchecked_unwrap pub trait UncheckedOptionExt<T> { |