Snap for 8730993 from 22d1a7967572fe2e4953ab21b39e96644f4eaabd to mainline-tzdata3-release
Change-Id: I99a5ae9e92bc9cc960c320b6d7fef9f729f737ca
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 38c6551..e1a0b04 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,5 @@
{
"git": {
- "sha1": "a75875b0bf904287a9749e8eabea919b5e9dd8a9"
- },
- "path_in_vcs": ""
-}
\ No newline at end of file
+ "sha1": "86969fd7baf94312520e0b5a5f3b0861a0fd411b"
+ }
+}
diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 4d33593..d613089 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -2,11 +2,11 @@
on:
push:
- branches:
- - trying
- - staging
+ branches-ignore:
+ - trying.tmp
+ - staging.tmp
pull_request:
-
+
env:
RUST_TEST_THREADS: 1
@@ -16,18 +16,15 @@
strategy:
matrix:
os: [ubuntu, macos, windows]
- channel: [1.49.0, stable, beta, nightly]
- feature: [arc_lock, serde, deadlock_detection]
+ channel: [1.36.0, stable, beta, nightly]
+ feature: [serde, deadlock_detection]
exclude:
- feature: deadlock_detection
- channel: '1.49.0'
+ channel: '1.36.0'
include:
- channel: nightly
feature: nightly
os: ubuntu
- - channel: nightly
- feature: hardware-lock-elision
- os: ubuntu
steps:
- uses: actions/checkout@v2
@@ -56,7 +53,7 @@
steps:
- uses: actions/checkout@v2
- run: rustup default nightly
- - run: cargo doc --workspace --features arc_lock,serde,deadlock_detection --no-deps -p parking_lot -p parking_lot_core -p lock_api
+ - run: cargo doc --workspace --features serde,deadlock_detection --no-deps -p parking_lot -p parking_lot_core -p lock_api
benchmark:
runs-on: ubuntu-latest
steps:
diff --git a/Android.bp b/Android.bp
index 17f0e2b..731530a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,5 +1,4 @@
-// This file is generated by cargo2android.py --config cargo2android.json.
-// Do not modify this file as changes will be overridden on upgrade.
+// This file is generated by cargo2android.py --run --device --dependencies.
package {
default_applicable_licenses: ["external_rust_crates_parking_lot_license"],
@@ -41,19 +40,22 @@
name: "libparking_lot",
host_supported: true,
crate_name: "parking_lot",
- cargo_env_compat: true,
- cargo_pkg_version: "0.12.0",
srcs: ["src/lib.rs"],
edition: "2018",
features: ["default"],
rustlibs: [
+ "libinstant",
"liblock_api",
"libparking_lot_core",
],
- apex_available: [
- "//apex_available:platform",
- "com.android.bluetooth",
- "com.android.virt",
- ],
- min_sdk_version: "29",
}
+
+// dependent_library ["feature_list"]
+// cfg-if-0.1.10
+// cfg-if-1.0.0
+// instant-0.1.8
+// libc-0.2.80 "default,std"
+// lock_api-0.4.2
+// parking_lot_core-0.8.0
+// scopeguard-1.1.0
+// smallvec-1.5.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d1951e9..a473463 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,41 +1,3 @@
-## parking_lot 0.12.0, parking_lot_core 0.9.0, lock_api 0.4.6 (2022-01-28)
-
-- The MSRV is bumped to 1.49.0.
-- Disabled eventual fairness on wasm32-unknown-unknown. (#302)
-- Added a rwlock method to report if lock is held exclusively. (#303)
-- Use new `asm!` macro. (#304)
-- Use windows-rs instead of winapi for faster builds. (#311)
-- Moved hardware lock elision support to a separate Cargo feature. (#313)
-- Removed used of deprecated `spin_loop_hint`. (#314)
-
-## parking_lot 0.11.2, parking_lot_core 0.8.4, lock_api 0.4.5 (2021-08-28)
-
-- Fixed incorrect memory orderings on `RwLock` and `WordLock`. (#294, #292)
-- Added `Arc`-based lock guards. (#291)
-- Added workaround for TSan's lack of support for `fence`. (#292)
-
-## lock_api 0.4.4 (2021-05-01)
-
-- Update for latest nightly. (#281)
-
-## lock_api 0.4.3 (2021-04-03)
-
-- Added `[Raw]ReentrantMutex::is_owned`. (#280)
-
-## parking_lot_core 0.8.3 (2021-02-12)
-
-- Updated smallvec to 1.6. (#276)
-
-## parking_lot_core 0.8.2 (2020-12-21)
-
-- Fixed assertion failure on OpenBSD. (#270)
-
-## parking_lot_core 0.8.1 (2020-12-04)
-
-- Removed deprecated CloudABI support. (#263)
-- Fixed build on wasm32-unknown-unknown. (#265)
-- Relaxed dependency on `smallvec`. (#266)
-
## parking_lot 0.11.1, lock_api 0.4.2 (2020-11-18)
- Fix bounds on Send and Sync impls for lock guards. (#262)
diff --git a/Cargo.toml b/Cargo.toml
index 6f58afa..c78888f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,16 +3,17 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
+# to registry (e.g., crates.io) dependencies
#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
[package]
edition = "2018"
name = "parking_lot"
-version = "0.12.0"
+version = "0.11.1"
authors = ["Amanieu d'Antras <amanieu@gmail.com>"]
description = "More compact and efficient implementations of the standard synchronization primitives."
readme = "README.md"
@@ -20,23 +21,26 @@
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.4.6"
+version = "0.4.0"
[dependencies.parking_lot_core]
-version = "0.9.0"
+version = "0.8.0"
[dev-dependencies.bincode]
-version = "1.3.3"
+version = "1.3.0"
[dev-dependencies.rand]
-version = "0.8.3"
+version = "0.7.3"
[features]
-arc_lock = ["lock_api/arc_lock"]
deadlock_detection = ["parking_lot_core/deadlock_detection"]
default = []
-hardware-lock-elision = []
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 bb501be..67a2555 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "parking_lot"
-version = "0.12.0"
+version = "0.11.1"
authors = ["Amanieu d'Antras <amanieu@gmail.com>"]
description = "More compact and efficient implementations of the standard synchronization primitives."
license = "Apache-2.0/MIT"
@@ -11,24 +11,25 @@
edition = "2018"
[dependencies]
-parking_lot_core = { path = "core", version = "0.9.0" }
-lock_api = { path = "lock_api", version = "0.4.6" }
+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.8.3"
+rand = "0.7.3"
# Used when testing out serde support.
-bincode = "1.3.3"
+bincode = "1.3.0"
[features]
default = []
-arc_lock = ["lock_api/arc_lock"]
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 = []
-hardware-lock-elision = []
[workspace]
exclude = ["benchmark"]
diff --git a/METADATA b/METADATA
index 10f98ed..d750618 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/parking_lot/parking_lot-0.12.0.crate"
+ value: "https://static.crates.io/crates/parking_lot/parking_lot-0.11.1.crate"
}
- version: "0.12.0"
+ version: "0.11.1"
license_type: NOTICE
last_upgrade_date {
- year: 2022
- month: 3
- day: 1
+ year: 2020
+ month: 11
+ day: 17
}
}
diff --git a/README.md b/README.md
index 5bda8d8..d3e5b0b 100644
--- a/README.md
+++ b/README.md
@@ -50,7 +50,6 @@
library versions of those types.
7. `RwLock` takes advantage of hardware lock elision on processors that
support it, which can lead to huge performance wins with many readers.
- This must be enabled with the `hardware-lock-elision` feature.
8. `RwLock` uses a task-fair locking policy, which avoids reader and writer
starvation, whereas the standard library version makes no guarantees.
9. `Condvar` is guaranteed not to produce spurious wakeups. A thread will
@@ -94,6 +93,8 @@
- You will have to use the `const_*` functions (e.g. `const_mutex(val)`) to
statically initialize the locking primitives. Using e.g. `Mutex::new(val)`
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`.
@@ -125,17 +126,13 @@
Note that the `deadlock_detection` and `send_guard` features are incompatible
and cannot be used together.
-Hardware lock elision support for x86 can be enabled with the
-`hardware-lock-elision` feature. This requires Rust 1.59 due to the use of
-inline assembly.
-
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`.
## Minimum Rust version
-The current minimum required Rust version is 1.49. Any change to this is
+The current minimum required Rust version is 1.36. Any change to this is
considered a breaking change and will require a major version bump.
## License
diff --git a/TEST_MAPPING b/TEST_MAPPING
deleted file mode 100644
index f439cf8..0000000
--- a/TEST_MAPPING
+++ /dev/null
@@ -1,8 +0,0 @@
-// Generated by update_crate_tests.py for tests that depend on this crate.
-{
- "imports": [
- {
- "path": "external/rust/crates/vulkano"
- }
- ]
-}
diff --git a/cargo2android.json b/cargo2android.json
deleted file mode 100644
index e48e3b8..0000000
--- a/cargo2android.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "apex-available": [
- "//apex_available:platform",
- "com.android.bluetooth",
- "com.android.virt"
- ],
- "device": true,
- "min-sdk-version": "29",
- "run": true
-}
diff --git a/src/condvar.rs b/src/condvar.rs
index 9eaf300..534b8af 100644
--- a/src/condvar.rs
+++ b/src/condvar.rs
@@ -12,9 +12,10 @@
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.
@@ -380,6 +381,12 @@
///
/// Like `wait`, the lock specified will be re-acquired when this function
/// returns, regardless of whether the timeout elapsed or not.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the given `timeout` is so large that it can't be added to the current time.
+ /// This panic is not possible if the crate is built with the `nightly` feature, then a too
+ /// large `timeout` becomes equivalent to just calling `wait`.
#[inline]
pub fn wait_for<T: ?Sized>(
&self,
@@ -407,11 +414,11 @@
#[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;
- use std::time::Instant;
#[test]
fn smoke() {
@@ -550,7 +557,14 @@
let _g = m2.lock();
c2.notify_one();
});
- let timeout_res = c.wait_for(&mut g, Duration::from_secs(u64::max_value()));
+ // Non-nightly panics on too large timeouts. Nightly treats it as indefinite wait.
+ let very_long_timeout = if cfg!(feature = "nightly") {
+ Duration::from_secs(u64::max_value())
+ } else {
+ Duration::from_millis(u32::max_value() as u64)
+ };
+
+ let timeout_res = c.wait_for(&mut g, very_long_timeout);
assert!(!timeout_res.timed_out());
drop(g);
diff --git a/src/elision.rs b/src/elision.rs
index 8fa229e..68cfa63 100644
--- a/src/elision.rs
+++ b/src/elision.rs
@@ -5,8 +5,6 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
-#[cfg(all(feature = "hardware-lock-elision", any(target_arch = "x86", target_arch = "x86_64")))]
-use std::arch::asm;
use std::sync::atomic::AtomicUsize;
// Extension trait to add lock elision primitives to atomic types
@@ -28,14 +26,14 @@
#[inline]
pub fn have_elision() -> bool {
cfg!(all(
- feature = "hardware-lock-elision",
+ feature = "nightly",
any(target_arch = "x86", target_arch = "x86_64"),
))
}
// This implementation is never actually called because it is guarded by
// have_elision().
-#[cfg(not(all(feature = "hardware-lock-elision", any(target_arch = "x86", target_arch = "x86_64"))))]
+#[cfg(not(all(feature = "nightly", any(target_arch = "x86", target_arch = "x86_64"))))]
impl AtomicElisionExt for AtomicUsize {
type IntType = usize;
@@ -50,33 +48,37 @@
}
}
-#[cfg(all(feature = "hardware-lock-elision", any(target_arch = "x86", target_arch = "x86_64")))]
+#[cfg(all(feature = "nightly", any(target_arch = "x86", target_arch = "x86_64")))]
impl AtomicElisionExt for AtomicUsize {
type IntType = usize;
+ #[cfg(target_pointer_width = "32")]
#[inline]
fn elision_compare_exchange_acquire(&self, current: usize, new: usize) -> Result<usize, usize> {
unsafe {
- use core::arch::asm;
let prev: usize;
- #[cfg(target_pointer_width = "32")]
- asm!(
- "xacquire",
- "lock",
- "cmpxchg [{:e}], {:e}",
- in(reg) self,
- in(reg) new,
- inout("eax") current => prev,
- );
- #[cfg(target_pointer_width = "64")]
- asm!(
- "xacquire",
- "lock",
- "cmpxchg [{}], {}",
- in(reg) self,
- in(reg) new,
- inout("rax") current => prev,
- );
+ llvm_asm!("xacquire; lock; cmpxchgl $2, $1"
+ : "={eax}" (prev), "+*m" (self)
+ : "r" (new), "{eax}" (current)
+ : "memory"
+ : "volatile");
+ if prev == current {
+ Ok(prev)
+ } else {
+ Err(prev)
+ }
+ }
+ }
+ #[cfg(target_pointer_width = "64")]
+ #[inline]
+ fn elision_compare_exchange_acquire(&self, current: usize, new: usize) -> Result<usize, usize> {
+ unsafe {
+ let prev: usize;
+ llvm_asm!("xacquire; lock; cmpxchgq $2, $1"
+ : "={rax}" (prev), "+*m" (self)
+ : "r" (new), "{rax}" (current)
+ : "memory"
+ : "volatile");
if prev == current {
Ok(prev)
} else {
@@ -85,27 +87,29 @@
}
}
+ #[cfg(target_pointer_width = "32")]
#[inline]
fn elision_fetch_sub_release(&self, val: usize) -> usize {
unsafe {
- use core::arch::asm;
let prev: usize;
- #[cfg(target_pointer_width = "32")]
- asm!(
- "xrelease",
- "lock",
- "xadd [{:e}], {:e}",
- in(reg) self,
- inout(reg) val.wrapping_neg() => prev,
- );
- #[cfg(target_pointer_width = "64")]
- asm!(
- "xrelease",
- "lock",
- "xadd [{}], {}",
- in(reg) self,
- inout(reg) val.wrapping_neg() => prev,
- );
+ llvm_asm!("xrelease; lock; xaddl $2, $1"
+ : "=r" (prev), "+*m" (self)
+ : "0" (val.wrapping_neg())
+ : "memory"
+ : "volatile");
+ prev
+ }
+ }
+ #[cfg(target_pointer_width = "64")]
+ #[inline]
+ fn elision_fetch_sub_release(&self, val: usize) -> usize {
+ unsafe {
+ let prev: usize;
+ llvm_asm!("xrelease; lock; xaddq $2, $1"
+ : "=r" (prev), "+*m" (self)
+ : "0" (val.wrapping_neg())
+ : "memory"
+ : "volatile");
prev
}
}
diff --git a/src/fair_mutex.rs b/src/fair_mutex.rs
index 3e4c163..449c53b 100644
--- a/src/fair_mutex.rs
+++ b/src/fair_mutex.rs
@@ -11,21 +11,24 @@
/// A mutual exclusive primitive that is always fair, useful for protecting shared data
///
/// This mutex will block threads waiting for the lock to become available. The
-/// mutex can be statically initialized or created by the `new`
+/// mutex can also be statically initialized or created via a `new`
/// constructor. Each mutex has a type parameter which represents the data that
/// it is protecting. The data can only be accessed through the RAII guards
/// returned from `lock` and `try_lock`, which guarantees that the data is only
/// ever accessed when the mutex is locked.
///
-/// The regular mutex provided by `parking_lot` uses eventual fairness
+/// The regular mutex provided by `parking_lot` uses eventual locking fairness
/// (after some time it will default to the fair algorithm), but eventual
-/// fairness does not provide the same guarantees an always fair method would.
-/// Fair mutexes are generally slower, but sometimes needed.
+/// fairness does not provide the same garantees a always fair method would.
+/// Fair mutexes are generally slower, but sometimes needed. This wrapper was
+/// created to avoid using a unfair protocol when it's forbidden by mistake.
///
-/// In a fair mutex the waiters form a queue, and the lock is always granted to
-/// the next requester in the queue, in first-in first-out order. This ensures
-/// that one thread cannot starve others by quickly re-acquiring the lock after
-/// releasing it.
+/// In a fair mutex the lock is provided to whichever thread asked first,
+/// they form a queue and always follow the first-in first-out order. This
+/// means some thread in the queue won't be able to steal the lock and use it fast
+/// to increase throughput, at the cost of latency. Since the response time will grow
+/// for some threads that are waiting for the lock and losing to faster but later ones,
+/// but it may make sending more responses possible.
///
/// A fair mutex may not be interesting if threads have different priorities (this is known as
/// priority inversion).
diff --git a/src/lib.rs b/src/lib.rs
index 03639a6..7ff2c79 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,6 +11,7 @@
#![warn(missing_docs)]
#![warn(rust_2018_idioms)]
+#![cfg_attr(feature = "nightly", feature(llvm_asm))]
mod condvar;
mod elision;
diff --git a/src/mutex.rs b/src/mutex.rs
index 71bc351..9f63cb9 100644
--- a/src/mutex.rs
+++ b/src/mutex.rs
@@ -11,7 +11,7 @@
/// A mutual exclusion primitive useful for protecting shared data
///
/// This mutex will block threads waiting for the lock to become available. The
-/// mutex can be statically initialized or created by the `new`
+/// mutex can also be statically initialized or created via a `new`
/// constructor. Each mutex has a type parameter which represents the data that
/// it is protecting. The data can only be accessed through the RAII guards
/// returned from `lock` and `try_lock`, which guarantees that the data is only
diff --git a/src/raw_mutex.rs b/src/raw_mutex.rs
index b1ae7ee..06667d3 100644
--- a/src/raw_mutex.rs
+++ b/src/raw_mutex.rs
@@ -10,9 +10,9 @@
sync::atomic::{AtomicU8, Ordering},
time::Duration,
};
+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.
diff --git a/src/raw_rwlock.rs b/src/raw_rwlock.rs
index 21d338b..75a9812 100644
--- a/src/raw_rwlock.rs
+++ b/src/raw_rwlock.rs
@@ -12,11 +12,12 @@
cell::Cell,
sync::atomic::{AtomicUsize, Ordering},
};
+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
@@ -143,12 +144,6 @@
let state = self.state.load(Ordering::Relaxed);
state & (WRITER_BIT | READERS_MASK) != 0
}
-
- #[inline]
- fn is_locked_exclusive(&self) -> bool {
- let state = self.state.load(Ordering::Relaxed);
- state & (WRITER_BIT) != 0
- }
}
unsafe impl lock_api::RawRwLockFair for RawRwLock {
@@ -367,7 +362,7 @@
unsafe fn upgrade(&self) {
let state = self.state.fetch_sub(
(ONE_READER | UPGRADABLE_BIT) - WRITER_BIT,
- Ordering::Acquire,
+ Ordering::Relaxed,
);
if state & READERS_MASK != ONE_READER {
let result = self.upgrade_slow(None);
@@ -382,7 +377,7 @@
.compare_exchange_weak(
ONE_READER | UPGRADABLE_BIT,
WRITER_BIT,
- Ordering::Acquire,
+ Ordering::Relaxed,
Ordering::Relaxed,
)
.is_ok()
diff --git a/src/rwlock.rs b/src/rwlock.rs
index 512114c..70e1b1a 100644
--- a/src/rwlock.rs
+++ b/src/rwlock.rs
@@ -408,8 +408,6 @@
write_result.is_none(),
"try_write should fail while read_guard is in scope"
);
- assert!(lock.is_locked());
- assert!(!lock.is_locked_exclusive());
drop(read_guard);
}
@@ -421,8 +419,6 @@
write_result.is_none(),
"try_write should fail while upgrade_guard is in scope"
);
- assert!(lock.is_locked());
- assert!(!lock.is_locked_exclusive());
drop(upgrade_guard);
}
@@ -434,8 +430,6 @@
write_result.is_none(),
"try_write should fail while write_guard is in scope"
);
- assert!(lock.is_locked());
- assert!(lock.is_locked_exclusive());
drop(write_guard);
}
@@ -621,22 +615,4 @@
.join()
.unwrap();
}
-
- #[test]
- fn test_rw_write_is_locked() {
- let lock = RwLock::new(0isize);
- {
- let _read_guard = lock.read();
-
- assert!(lock.is_locked());
- assert!(!lock.is_locked_exclusive());
- }
-
- {
- let _write_guard = lock.write();
-
- assert!(lock.is_locked());
- assert!(lock.is_locked_exclusive());
- }
- }
}
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> {