diff -Nru rust-parking-lot-0.11.2/Cargo.toml rust-parking-lot-0.12.1/Cargo.toml --- rust-parking-lot-0.11.2/Cargo.toml 1970-01-01 00:00:01.000000000 +0000 +++ rust-parking-lot-0.12.1/Cargo.toml 1970-01-01 00:00:01.000000000 +0000 @@ -12,22 +12,27 @@ [package] edition = "2018" name = "parking_lot" -version = "0.11.2" +version = "0.12.1" authors = ["Amanieu d'Antras "] description = "More compact and efficient implementations of the standard synchronization primitives." readme = "README.md" -keywords = ["mutex", "condvar", "rwlock", "once", "thread"] +keywords = [ + "mutex", + "condvar", + "rwlock", + "once", + "thread", +] categories = ["concurrency"] -license = "Apache-2.0/MIT" +license = "MIT OR Apache-2.0" repository = "https://github.com/Amanieu/parking_lot" -[dependencies.instant] -version = "0.1.9" [dependencies.lock_api] -version = "0.4.5" +version = "0.4.6" [dependencies.parking_lot_core] -version = "0.8.4" +version = "0.9.0" + [dev-dependencies.bincode] version = "1.3.3" @@ -38,9 +43,11 @@ arc_lock = ["lock_api/arc_lock"] deadlock_detection = ["parking_lot_core/deadlock_detection"] default = [] -nightly = ["parking_lot_core/nightly", "lock_api/nightly"] +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 -Nru rust-parking-lot-0.11.2/Cargo.toml.orig rust-parking-lot-0.12.1/Cargo.toml.orig --- rust-parking-lot-0.11.2/Cargo.toml.orig 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/Cargo.toml.orig 1973-11-29 21:33:09.000000000 +0000 @@ -1,9 +1,9 @@ [package] name = "parking_lot" -version = "0.11.2" +version = "0.12.1" authors = ["Amanieu d'Antras "] description = "More compact and efficient implementations of the standard synchronization primitives." -license = "Apache-2.0/MIT" +license = "MIT OR Apache-2.0" repository = "https://github.com/Amanieu/parking_lot" readme = "README.md" keywords = ["mutex", "condvar", "rwlock", "once", "thread"] @@ -11,9 +11,8 @@ edition = "2018" [dependencies] -parking_lot_core = { path = "core", version = "0.8.4" } -lock_api = { path = "lock_api", version = "0.4.5" } -instant = "0.1.9" +parking_lot_core = { path = "core", version = "0.9.0" } +lock_api = { path = "lock_api", version = "0.4.6" } [dev-dependencies] rand = "0.8.3" @@ -28,9 +27,8 @@ 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 -Nru rust-parking-lot-0.11.2/.cargo_vcs_info.json rust-parking-lot-0.12.1/.cargo_vcs_info.json --- rust-parking-lot-0.11.2/.cargo_vcs_info.json 1970-01-01 00:00:01.000000000 +0000 +++ rust-parking-lot-0.12.1/.cargo_vcs_info.json 1970-01-01 00:00:01.000000000 +0000 @@ -1,5 +1,6 @@ { "git": { - "sha1": "18001b819c1539c06c176c671bbe54e70b5c3d69" - } -} + "sha1": "336a9b31ff385728d00eb7ef173e4d054584b787" + }, + "path_in_vcs": "" +} \ No newline at end of file diff -Nru rust-parking-lot-0.11.2/CHANGELOG.md rust-parking-lot-0.12.1/CHANGELOG.md --- rust-parking-lot-0.11.2/CHANGELOG.md 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/CHANGELOG.md 1973-11-29 21:33:09.000000000 +0000 @@ -1,3 +1,34 @@ +## parking_lot 0.12.1 (2022-05-31) + +- Fixed incorrect memory ordering in `RwLock`. (#344) +- Added `Condvar::wait_while` convenience methods (#343) + +## parking_lot_core 0.9.3 (2022-04-30) + +- Bump windows-sys dependency to 0.36. (#339) + +## parking_lot_core 0.9.2, lock_api 0.4.7 (2022-03-25) + +- Enable const new() on lock types on stable. (#325) +- Added `MutexGuard::leak` function. (#333) +- Bump windows-sys dependency to 0.34. (#331) +- Bump petgraph dependency to 0.6. (#326) +- Don't use pthread attributes on the espidf platform. (#319) + +## parking_lot_core 0.9.1 (2022-02-06) + +- Bump windows-sys dependency to 0.32. (#316) + +## 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) diff -Nru rust-parking-lot-0.11.2/debian/cargo-checksum.json rust-parking-lot-0.12.1/debian/cargo-checksum.json --- rust-parking-lot-0.11.2/debian/cargo-checksum.json 2022-06-01 21:32:03.000000000 +0000 +++ rust-parking-lot-0.12.1/debian/cargo-checksum.json 2022-09-02 17:16:53.000000000 +0000 @@ -1 +1 @@ -{"package":"Could not get crate checksum","files":{}} +{"package":"3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f","files":{}} diff -Nru rust-parking-lot-0.11.2/debian/changelog rust-parking-lot-0.12.1/debian/changelog --- rust-parking-lot-0.11.2/debian/changelog 2022-06-01 21:32:03.000000000 +0000 +++ rust-parking-lot-0.12.1/debian/changelog 2022-09-02 17:16:53.000000000 +0000 @@ -1,3 +1,15 @@ +rust-parking-lot (0.12.1-1) unstable; urgency=medium + + * Team upload. + * Package parking_lot 0.12.1 from crates.io using debcargo 2.5.0 + * Drop outdated patch removing stdweb + + [ Simon Chopin ] + * Mark the "deadlock_detection" tests as test_is_broken because of the + patched-out backtrace dependency in -core. + + -- Blair Noctis Fri, 02 Sep 2022 19:16:53 +0200 + rust-parking-lot (0.11.2-2) unstable; urgency=medium * Package parking_lot 0.11.2 from crates.io using debcargo 2.5.0 diff -Nru rust-parking-lot-0.11.2/debian/control rust-parking-lot-0.12.1/debian/control --- rust-parking-lot-0.11.2/debian/control 2022-06-01 21:32:03.000000000 +0000 +++ rust-parking-lot-0.12.1/debian/control 2022-09-02 17:16:53.000000000 +0000 @@ -6,9 +6,8 @@ cargo:native , rustc:native , libstd-rust-dev , - librust-instant-0.1+default-dev (>= 0.1.9-~~) , - librust-lock-api-0.4+default-dev (>= 0.4.5-~~) , - librust-parking-lot-core-0.8+default-dev (>= 0.8.4-~~) + librust-lock-api-0.4+default-dev (>= 0.4.6-~~) , + librust-parking-lot-core-0.9+default-dev Maintainer: Debian Rust Maintainers Uploaders: Sylvestre Ledru , @@ -24,52 +23,50 @@ Multi-Arch: same Depends: ${misc:Depends}, - librust-instant-0.1+default-dev (>= 0.1.9-~~), - librust-instant-0.1+wasm-bindgen-dev (>= 0.1.9-~~), - librust-lock-api-0.4+arc-lock-dev (>= 0.4.5-~~), - librust-lock-api-0.4+default-dev (>= 0.4.5-~~), - librust-lock-api-0.4+nightly-dev (>= 0.4.5-~~), - librust-lock-api-0.4+owning-ref-dev (>= 0.4.5-~~), - librust-lock-api-0.4+serde-dev (>= 0.4.5-~~), - librust-parking-lot-core-0.8+deadlock-detection-dev (>= 0.8.4-~~), - librust-parking-lot-core-0.8+default-dev (>= 0.8.4-~~), - librust-parking-lot-core-0.8+nightly-dev (>= 0.8.4-~~) + librust-lock-api-0.4+arc-lock-dev (>= 0.4.6-~~), + librust-lock-api-0.4+default-dev (>= 0.4.6-~~), + librust-lock-api-0.4+nightly-dev (>= 0.4.6-~~), + librust-lock-api-0.4+owning-ref-dev (>= 0.4.6-~~), + librust-lock-api-0.4+serde-dev (>= 0.4.6-~~), + librust-parking-lot-core-0.9+deadlock-detection-dev, + librust-parking-lot-core-0.9+default-dev, + librust-parking-lot-core-0.9+nightly-dev Provides: librust-parking-lot+arc-lock-dev (= ${binary:Version}), librust-parking-lot+deadlock-detection-dev (= ${binary:Version}), librust-parking-lot+default-dev (= ${binary:Version}), + librust-parking-lot+hardware-lock-elision-dev (= ${binary:Version}), librust-parking-lot+nightly-dev (= ${binary:Version}), librust-parking-lot+owning-ref-dev (= ${binary:Version}), librust-parking-lot+send-guard-dev (= ${binary:Version}), librust-parking-lot+serde-dev (= ${binary:Version}), - librust-parking-lot+wasm-bindgen-dev (= ${binary:Version}), librust-parking-lot-0-dev (= ${binary:Version}), librust-parking-lot-0+arc-lock-dev (= ${binary:Version}), librust-parking-lot-0+deadlock-detection-dev (= ${binary:Version}), librust-parking-lot-0+default-dev (= ${binary:Version}), + librust-parking-lot-0+hardware-lock-elision-dev (= ${binary:Version}), librust-parking-lot-0+nightly-dev (= ${binary:Version}), librust-parking-lot-0+owning-ref-dev (= ${binary:Version}), librust-parking-lot-0+send-guard-dev (= ${binary:Version}), librust-parking-lot-0+serde-dev (= ${binary:Version}), - librust-parking-lot-0+wasm-bindgen-dev (= ${binary:Version}), - librust-parking-lot-0.11-dev (= ${binary:Version}), - librust-parking-lot-0.11+arc-lock-dev (= ${binary:Version}), - librust-parking-lot-0.11+deadlock-detection-dev (= ${binary:Version}), - librust-parking-lot-0.11+default-dev (= ${binary:Version}), - librust-parking-lot-0.11+nightly-dev (= ${binary:Version}), - librust-parking-lot-0.11+owning-ref-dev (= ${binary:Version}), - librust-parking-lot-0.11+send-guard-dev (= ${binary:Version}), - librust-parking-lot-0.11+serde-dev (= ${binary:Version}), - librust-parking-lot-0.11+wasm-bindgen-dev (= ${binary:Version}), - librust-parking-lot-0.11.2-dev (= ${binary:Version}), - librust-parking-lot-0.11.2+arc-lock-dev (= ${binary:Version}), - librust-parking-lot-0.11.2+deadlock-detection-dev (= ${binary:Version}), - librust-parking-lot-0.11.2+default-dev (= ${binary:Version}), - librust-parking-lot-0.11.2+nightly-dev (= ${binary:Version}), - librust-parking-lot-0.11.2+owning-ref-dev (= ${binary:Version}), - librust-parking-lot-0.11.2+send-guard-dev (= ${binary:Version}), - librust-parking-lot-0.11.2+serde-dev (= ${binary:Version}), - librust-parking-lot-0.11.2+wasm-bindgen-dev (= ${binary:Version}) + librust-parking-lot-0.12-dev (= ${binary:Version}), + librust-parking-lot-0.12+arc-lock-dev (= ${binary:Version}), + librust-parking-lot-0.12+deadlock-detection-dev (= ${binary:Version}), + librust-parking-lot-0.12+default-dev (= ${binary:Version}), + librust-parking-lot-0.12+hardware-lock-elision-dev (= ${binary:Version}), + librust-parking-lot-0.12+nightly-dev (= ${binary:Version}), + librust-parking-lot-0.12+owning-ref-dev (= ${binary:Version}), + librust-parking-lot-0.12+send-guard-dev (= ${binary:Version}), + librust-parking-lot-0.12+serde-dev (= ${binary:Version}), + librust-parking-lot-0.12.1-dev (= ${binary:Version}), + librust-parking-lot-0.12.1+arc-lock-dev (= ${binary:Version}), + librust-parking-lot-0.12.1+deadlock-detection-dev (= ${binary:Version}), + librust-parking-lot-0.12.1+default-dev (= ${binary:Version}), + librust-parking-lot-0.12.1+hardware-lock-elision-dev (= ${binary:Version}), + librust-parking-lot-0.12.1+nightly-dev (= ${binary:Version}), + librust-parking-lot-0.12.1+owning-ref-dev (= ${binary:Version}), + librust-parking-lot-0.12.1+send-guard-dev (= ${binary:Version}), + librust-parking-lot-0.12.1+serde-dev (= ${binary:Version}) Description: Compact, efficient std sync primitives - Rust source code This package contains the source for the Rust parking_lot crate, packaged by debcargo for use with cargo and dh-cargo. diff -Nru rust-parking-lot-0.11.2/debian/copyright.debcargo.hint rust-parking-lot-0.12.1/debian/copyright.debcargo.hint --- rust-parking-lot-0.11.2/debian/copyright.debcargo.hint 2022-06-01 21:32:03.000000000 +0000 +++ rust-parking-lot-0.12.1/debian/copyright.debcargo.hint 2022-09-02 17:16:53.000000000 +0000 @@ -5,7 +5,7 @@ Files: * Copyright: FIXME (overlay) UNKNOWN-YEARS Amanieu d'Antras -License: Apache-2.0 or MIT +License: MIT or Apache-2.0 Comment: FIXME (overlay): Since upstream copyright years are not available in Cargo.toml, they were extracted from the upstream Git repository. This may not @@ -108,7 +108,7 @@ 2018-2022 Debian Rust Maintainers 2018-2022 Sylvestre Ledru 2018-2022 Wolfgang Silbermayr -License: Apache-2.0 or MIT +License: MIT or Apache-2.0 License: Apache-2.0 Debian systems provide the Apache 2.0 license in diff -Nru rust-parking-lot-0.11.2/debian/debcargo.toml rust-parking-lot-0.12.1/debian/debcargo.toml --- rust-parking-lot-0.11.2/debian/debcargo.toml 2022-06-01 21:32:03.000000000 +0000 +++ rust-parking-lot-0.12.1/debian/debcargo.toml 2022-09-02 17:16:53.000000000 +0000 @@ -11,3 +11,7 @@ [packages."lib+nightly"] test_is_broken = true + +# Broken by the removal of backtrace dep from parking-lot-core +[packages."lib+deadlock_detection"] +test_is_broken = true diff -Nru rust-parking-lot-0.11.2/debian/patches/disable-stdweb.diff rust-parking-lot-0.12.1/debian/patches/disable-stdweb.diff --- rust-parking-lot-0.11.2/debian/patches/disable-stdweb.diff 2022-06-01 21:32:03.000000000 +0000 +++ rust-parking-lot-0.12.1/debian/patches/disable-stdweb.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -Index: parking-lot/Cargo.toml -=================================================================== ---- parking-lot.orig/Cargo.toml -+++ parking-lot/Cargo.toml -@@ -42,5 +42,5 @@ nightly = ["parking_lot_core/nightly", " - owning_ref = ["lock_api/owning_ref"] - send_guard = [] - serde = ["lock_api/serde"] --stdweb = ["instant/stdweb"] -+#stdweb = ["instant/stdweb"] - wasm-bindgen = ["instant/wasm-bindgen"] diff -Nru rust-parking-lot-0.11.2/debian/patches/series rust-parking-lot-0.12.1/debian/patches/series --- rust-parking-lot-0.11.2/debian/patches/series 2022-06-01 21:32:03.000000000 +0000 +++ rust-parking-lot-0.12.1/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -disable-stdweb.diff diff -Nru rust-parking-lot-0.11.2/debian/tests/control rust-parking-lot-0.12.1/debian/tests/control --- rust-parking-lot-0.11.2/debian/tests/control 2022-06-01 21:32:03.000000000 +0000 +++ rust-parking-lot-0.12.1/debian/tests/control 2022-09-02 17:16:53.000000000 +0000 @@ -1,49 +1,49 @@ -Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.11.2 --all-targets --all-features +Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.12.1 --all-targets --all-features Features: test-name=rust-parking-lot:@ Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ Restrictions: allow-stderr, skip-not-installable, flaky -Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.11.2 --all-targets --no-default-features --features arc_lock +Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.12.1 --all-targets --no-default-features --features arc_lock Features: test-name=librust-parking-lot-dev:arc_lock Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ Restrictions: allow-stderr, skip-not-installable -Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.11.2 --all-targets --no-default-features --features deadlock_detection +Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.12.1 --all-targets --no-default-features --features deadlock_detection Features: test-name=librust-parking-lot-dev:deadlock_detection Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ -Restrictions: allow-stderr, skip-not-installable +Restrictions: allow-stderr, skip-not-installable, flaky -Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.11.2 --all-targets +Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.12.1 --all-targets Features: test-name=librust-parking-lot-dev:default Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ Restrictions: allow-stderr, skip-not-installable -Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.11.2 --all-targets --no-default-features --features nightly +Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.12.1 --all-targets --no-default-features --features hardware-lock-elision +Features: test-name=librust-parking-lot-dev:hardware-lock-elision +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.12.1 --all-targets --no-default-features --features nightly Features: test-name=librust-parking-lot-dev:nightly Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ Restrictions: allow-stderr, skip-not-installable, flaky -Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.11.2 --all-targets --no-default-features --features owning_ref +Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.12.1 --all-targets --no-default-features --features owning_ref Features: test-name=librust-parking-lot-dev:owning_ref Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ Restrictions: allow-stderr, skip-not-installable -Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.11.2 --all-targets --no-default-features --features send_guard +Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.12.1 --all-targets --no-default-features --features send_guard Features: test-name=librust-parking-lot-dev:send_guard Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ Restrictions: allow-stderr, skip-not-installable -Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.11.2 --all-targets --no-default-features --features serde +Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.12.1 --all-targets --no-default-features --features serde Features: test-name=librust-parking-lot-dev:serde Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ Restrictions: allow-stderr, skip-not-installable -Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.11.2 --all-targets --no-default-features --features wasm-bindgen -Features: test-name=librust-parking-lot-dev:wasm-bindgen -Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ -Restrictions: allow-stderr, skip-not-installable - -Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.11.2 --all-targets --no-default-features +Test-Command: /usr/share/cargo/bin/cargo-auto-test parking_lot 0.12.1 --all-targets --no-default-features Features: test-name=librust-parking-lot-dev: Depends: dh-cargo (>= 18), librust-bincode-1+default-dev (>= 1.3.3-~~), librust-rand-0.8+default-dev (>= 0.8.3-~~), @ Restrictions: allow-stderr, skip-not-installable diff -Nru rust-parking-lot-0.11.2/.github/workflows/rust.yml rust-parking-lot-0.12.1/.github/workflows/rust.yml --- rust-parking-lot-0.11.2/.github/workflows/rust.yml 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/.github/workflows/rust.yml 1973-11-29 21:33:09.000000000 +0000 @@ -2,12 +2,13 @@ on: push: - branches-ignore: - - trying.tmp - - staging.tmp + branches: + - trying + - staging pull_request: - + env: + CARGO_INCREMENTAL: 0 RUST_TEST_THREADS: 1 jobs: @@ -18,13 +19,16 @@ os: [ubuntu, macos, windows] channel: [1.49.0, stable, beta, nightly] feature: [arc_lock, serde, deadlock_detection] - exclude: + exclude: - feature: deadlock_detection channel: '1.49.0' include: - channel: nightly feature: nightly os: ubuntu + - channel: nightly + feature: hardware-lock-elision + os: ubuntu steps: - uses: actions/checkout@v2 @@ -38,7 +42,7 @@ runs-on: ubuntu-latest strategy: matrix: - target: + target: - wasm32-unknown-unknown - x86_64-fortanix-unknown-sgx #- x86_64-unknown-redox diff -Nru rust-parking-lot-0.11.2/README.md rust-parking-lot-0.12.1/README.md --- rust-parking-lot-0.11.2/README.md 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/README.md 1973-11-29 21:33:09.000000000 +0000 @@ -1,7 +1,7 @@ parking_lot ============ -![Rust](https://github.com/Amanieu/parking_lot/workflows/Rust/badge.svg) +[![Rust](https://github.com/Amanieu/parking_lot/workflows/Rust/badge.svg)](https://github.com/Amanieu/parking_lot/actions) [![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/) @@ -50,6 +50,7 @@ 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 @@ -82,7 +83,7 @@ based on the Webkit [`WTF::ParkingLot`](https://webkit.org/blog/6161/locking-in-webkit/) class, which essentially consists of a hash table mapping of lock addresses to queues of parked (sleeping) threads. The Webkit parking lot was itself -inspired by Linux [futexes](http://man7.org/linux/man-pages/man2/futex.2.html), +inspired by Linux [futexes](https://man7.org/linux/man-pages/man2/futex.2.html), but it is more powerful since it allows invoking callbacks while holding a queue lock. @@ -90,13 +91,13 @@ There are a few restrictions when using this library on stable Rust: -- 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`. +- The `wasm32-unknown-unknown` target is only fully supported on nightly with + `-C target-feature=+atomics` in `RUSTFLAGS` and `-Z build-std` passed to cargo. + parking_lot will work mostly fine on stable, the only difference is it will + panic instead of block forever if you hit a deadlock. + Just make sure not to enable `-C target-feature=+atomics` on stable as that + will allow wasm to run with multiple threads which will completely break + parking_lot's concurrency guarantees. To enable nightly-only functionality, you need to enable the `nightly` feature in Cargo (see below). @@ -107,14 +108,14 @@ ```toml [dependencies] -parking_lot = "0.11" +parking_lot = "0.12" ``` To enable nightly-only features, add this to your `Cargo.toml` instead: ```toml [dependencies] -parking_lot = { version = "0.11", features = ["nightly"] } +parking_lot = { version = "0.12", features = ["nightly"] } ``` The experimental deadlock detector can be enabled with the @@ -126,21 +127,25 @@ 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.36. Any change to this is +The current minimum required Rust version is 1.49. Any change to this is considered a breaking change and will require a major version bump. ## License Licensed under either of - * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT) at your option. diff -Nru rust-parking-lot-0.11.2/src/condvar.rs rust-parking-lot-0.12.1/src/condvar.rs --- rust-parking-lot-0.11.2/src/condvar.rs 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/src/condvar.rs 1973-11-29 21:33:09.000000000 +0000 @@ -12,10 +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; +use std::ops::DerefMut; +use std::time::{Duration, Instant}; /// A type indicating whether a timed wait on a condition variable returned /// due to a time out or not. @@ -54,7 +54,7 @@ /// woken up. /// - Only requires 1 word of space, whereas the standard library boxes the /// `Condvar` due to platform limitations. -/// - Can be statically constructed (requires the `const_fn` nightly feature). +/// - Can be statically constructed. /// - Does not require any drop glue when dropped. /// - Inline fast path for the uncontended case. /// @@ -137,10 +137,9 @@ #[cold] fn notify_one_slow(&self, mutex: *mut RawMutex) -> bool { - unsafe { - // Unpark one thread and requeue the rest onto the mutex - let from = self as *const _ as usize; - let to = mutex as usize; + // Unpark one thread and requeue the rest onto the mutex + let from = self as *const _ as usize; + let to = mutex as usize; let validate = || { // Make sure that our atomic state still points to the same // mutex. If not then it means that all threads on the current @@ -157,7 +156,7 @@ // locking the queue. There is the possibility of a race if the // mutex gets locked after we check, but that doesn't matter in // this case. - if (*mutex).mark_parked_if_locked() { + if unsafe { (*mutex).mark_parked_if_locked() } { RequeueOp::RequeueOne } else { RequeueOp::UnparkOne @@ -170,10 +169,9 @@ } TOKEN_NORMAL }; - let res = parking_lot_core::unpark_requeue(from, to, validate, callback); + let res = unsafe { parking_lot_core::unpark_requeue(from, to, validate, callback) }; res.unparked_threads + res.requeued_threads != 0 - } } /// Wakes up all blocked threads on this condvar. @@ -198,7 +196,6 @@ #[cold] fn notify_all_slow(&self, mutex: *mut RawMutex) -> usize { - unsafe { // Unpark one thread and requeue the rest onto the mutex let from = self as *const _ as usize; let to = mutex as usize; @@ -222,7 +219,7 @@ // locking the queue. There is the possibility of a race if the // mutex gets locked after we check, but that doesn't matter in // this case. - if (*mutex).mark_parked_if_locked() { + if unsafe { (*mutex).mark_parked_if_locked() } { RequeueOp::RequeueAll } else { RequeueOp::UnparkOneRequeueRest @@ -232,14 +229,13 @@ // If we requeued threads to the mutex, mark it as having // parked threads. The RequeueAll case is already handled above. if op == RequeueOp::UnparkOneRequeueRest && result.requeued_threads != 0 { - (*mutex).mark_parked(); + unsafe { (*mutex).mark_parked() }; } TOKEN_NORMAL }; - let res = parking_lot_core::unpark_requeue(from, to, validate, callback); + let res = unsafe { parking_lot_core::unpark_requeue(from, to, validate, callback) }; res.unparked_threads + res.requeued_threads - } } /// Blocks the current thread until this condition variable receives a @@ -298,7 +294,6 @@ // This is a non-generic function to reduce the monomorphization cost of // using `wait_until`. fn wait_until_internal(&self, mutex: &RawMutex, timeout: Option) -> WaitTimeoutResult { - unsafe { let result; let mut bad_mutex = false; let mut requeued = false; @@ -320,7 +315,7 @@ }; let before_sleep = || { // Unlock the mutex before sleeping... - mutex.unlock(); + unsafe { mutex.unlock() }; }; let timed_out = |k, was_last_thread| { // If we were requeued to a mutex, then we did not time out. @@ -335,14 +330,14 @@ self.state.store(ptr::null_mut(), Ordering::Relaxed); } }; - result = parking_lot_core::park( + result = unsafe { parking_lot_core::park( addr, validate, before_sleep, timed_out, DEFAULT_PARK_TOKEN, timeout, - ); + ) }; } // Panic if we tried to use multiple mutexes with a Condvar. Note @@ -354,13 +349,12 @@ // ... and re-lock it once we are done sleeping if result == ParkResult::Unparked(TOKEN_HANDOFF) { - deadlock::acquire_resource(mutex as *const _ as usize); + unsafe { deadlock::acquire_resource(mutex as *const _ as usize) }; } else { mutex.lock(); } WaitTimeoutResult(!(result.is_unparked() || requeued)) - } } /// Waits on this condition variable for a notification, timing out after a @@ -381,12 +375,6 @@ /// /// 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( &self, @@ -396,6 +384,127 @@ let deadline = util::to_deadline(timeout); self.wait_until_internal(unsafe { MutexGuard::mutex(mutex_guard).raw() }, deadline) } + + #[inline] + fn wait_while_until_internal( + &self, + mutex_guard: &mut MutexGuard<'_, T>, + mut condition: F, + timeout: Option, + ) -> WaitTimeoutResult + where + T: ?Sized, + F: FnMut(&mut T) -> bool, + { + let mut result = WaitTimeoutResult(false); + + while !result.timed_out() && condition(mutex_guard.deref_mut()) { + result = + self.wait_until_internal(unsafe { MutexGuard::mutex(mutex_guard).raw() }, timeout); + } + + result + } + /// Blocks the current thread until this condition variable receives a + /// notification. If the provided condition evaluates to `false`, then the + /// thread is no longer blocked and the operation is completed. If the + /// condition evaluates to `true`, then the thread is blocked again and + /// waits for another notification before repeating this process. + /// + /// This function will atomically unlock the mutex specified (represented by + /// `mutex_guard`) and block the current thread. This means that any calls + /// to `notify_*()` which happen logically after the mutex is unlocked are + /// candidates to wake this thread up. When this function call returns, the + /// lock specified will have been re-acquired. + /// + /// # Panics + /// + /// This function will panic if another thread is waiting on the `Condvar` + /// with a different `Mutex` object. + #[inline] + pub fn wait_while(&self, mutex_guard: &mut MutexGuard<'_, T>, condition: F) + where + T: ?Sized, + F: FnMut(&mut T) -> bool, + { + self.wait_while_until_internal(mutex_guard, condition, None); + } + + /// Waits on this condition variable for a notification, timing out after + /// the specified time instant. If the provided condition evaluates to + /// `false`, then the thread is no longer blocked and the operation is + /// completed. If the condition evaluates to `true`, then the thread is + /// blocked again and waits for another notification before repeating + /// this process. + /// + /// The semantics of this function are equivalent to `wait()` except that + /// the thread will be blocked roughly until `timeout` is reached. This + /// method should not be used for precise timing due to anomalies such as + /// preemption or platform differences that may not cause the maximum + /// amount of time waited to be precisely `timeout`. + /// + /// Note that the best effort is made to ensure that the time waited is + /// measured with a monotonic clock, and not affected by the changes made to + /// the system time. + /// + /// The returned `WaitTimeoutResult` value indicates if the timeout is + /// known to have elapsed. + /// + /// Like `wait`, the lock specified will be re-acquired when this function + /// returns, regardless of whether the timeout elapsed or not. + /// + /// # Panics + /// + /// This function will panic if another thread is waiting on the `Condvar` + /// with a different `Mutex` object. + #[inline] + pub fn wait_while_until( + &self, + mutex_guard: &mut MutexGuard<'_, T>, + condition: F, + timeout: Instant, + ) -> WaitTimeoutResult + where + T: ?Sized, + F: FnMut(&mut T) -> bool, + { + self.wait_while_until_internal(mutex_guard, condition, Some(timeout)) + } + + /// Waits on this condition variable for a notification, timing out after a + /// specified duration. If the provided condition evaluates to `false`, + /// then the thread is no longer blocked and the operation is completed. + /// If the condition evaluates to `true`, then the thread is blocked again + /// and waits for another notification before repeating this process. + /// + /// The semantics of this function are equivalent to `wait()` except that + /// the thread will be blocked for roughly no longer than `timeout`. This + /// method should not be used for precise timing due to anomalies such as + /// preemption or platform differences that may not cause the maximum + /// amount of time waited to be precisely `timeout`. + /// + /// Note that the best effort is made to ensure that the time waited is + /// measured with a monotonic clock, and not affected by the changes made to + /// the system time. + /// + /// The returned `WaitTimeoutResult` value indicates if the timeout is + /// known to have elapsed. + /// + /// Like `wait`, the lock specified will be re-acquired when this function + /// returns, regardless of whether the timeout elapsed or not. + #[inline] + pub fn wait_while_for( + &self, + mutex_guard: &mut MutexGuard<'_, T>, + condition: F, + timeout: Duration, + ) -> WaitTimeoutResult + where + F: FnMut(&mut T) -> bool, + { + let deadline = util::to_deadline(timeout); + self.wait_while_until_internal(mutex_guard, condition, deadline) + } } impl Default for Condvar { @@ -414,11 +523,13 @@ #[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::thread::sleep; + use std::thread::JoinHandle; use std::time::Duration; + use std::time::Instant; #[test] fn smoke() { @@ -557,14 +668,7 @@ let _g = m2.lock(); c2.notify_one(); }); - // 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); + let timeout_res = c.wait_for(&mut g, Duration::from_secs(u64::max_value())); assert!(!timeout_res.timed_out()); drop(g); @@ -592,6 +696,116 @@ drop(g); } + fn spawn_wait_while_notifier( + mutex: Arc>, + cv: Arc, + num_iters: u32, + timeout: Option, + ) -> JoinHandle<()> { + thread::spawn(move || { + for epoch in 1..=num_iters { + // spin to wait for main test thread to block + // before notifying it to wake back up and check + // its condition. + let mut sleep_backoff = Duration::from_millis(1); + let _mutex_guard = loop { + let mutex_guard = mutex.lock(); + + if let Some(timeout) = timeout { + if Instant::now() >= timeout { + return; + } + } + + if *mutex_guard == epoch { + break mutex_guard; + } + + drop(mutex_guard); + + // give main test thread a good chance to + // acquire the lock before this thread does. + sleep(sleep_backoff); + sleep_backoff *= 2; + }; + + cv.notify_one(); + } + }) + } + + #[test] + fn wait_while_until_internal_does_not_wait_if_initially_false() { + let mutex = Arc::new(Mutex::new(0)); + let cv = Arc::new(Condvar::new()); + + let condition = |counter: &mut u32| { + *counter += 1; + false + }; + + let mut mutex_guard = mutex.lock(); + let timeout_result = cv + .wait_while_until_internal(&mut mutex_guard, condition, None); + + assert!(!timeout_result.timed_out()); + assert!(*mutex_guard == 1); + } + + #[test] + fn wait_while_until_internal_times_out_before_false() { + let mutex = Arc::new(Mutex::new(0)); + let cv = Arc::new(Condvar::new()); + + let num_iters = 3; + let condition = |counter: &mut u32| { + *counter += 1; + true + }; + + let mut mutex_guard = mutex.lock(); + let timeout = Some(Instant::now() + Duration::from_millis(500)); + let handle = spawn_wait_while_notifier(mutex.clone(), cv.clone(), num_iters, timeout); + + let timeout_result = + cv.wait_while_until_internal(&mut mutex_guard, condition, timeout); + + assert!(timeout_result.timed_out()); + assert!(*mutex_guard == num_iters + 1); + + // prevent deadlock with notifier + drop(mutex_guard); + handle.join().unwrap(); + } + + #[test] + fn wait_while_until_internal() { + let mutex = Arc::new(Mutex::new(0)); + let cv = Arc::new(Condvar::new()); + + let num_iters = 4; + + let condition = |counter: &mut u32| { + *counter += 1; + *counter <= num_iters + }; + + let mut mutex_guard = mutex.lock(); + let handle = spawn_wait_while_notifier(mutex.clone(), cv.clone(), num_iters, None); + + let timeout_result = + cv.wait_while_until_internal(&mut mutex_guard, condition, None); + + assert!(!timeout_result.timed_out()); + assert!(*mutex_guard == num_iters + 1); + + let timeout_result = cv.wait_while_until_internal(&mut mutex_guard, condition, None); + handle.join().unwrap(); + + assert!(!timeout_result.timed_out()); + assert!(*mutex_guard == num_iters + 2); + } + #[test] #[should_panic] fn two_mutexes() { diff -Nru rust-parking-lot-0.11.2/src/elision.rs rust-parking-lot-0.12.1/src/elision.rs --- rust-parking-lot-0.11.2/src/elision.rs 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/src/elision.rs 1973-11-29 21:33:09.000000000 +0000 @@ -5,6 +5,8 @@ // 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 @@ -26,14 +28,14 @@ #[inline] pub fn have_elision() -> bool { cfg!(all( - feature = "nightly", + feature = "hardware-lock-elision", 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 = "nightly", any(target_arch = "x86", target_arch = "x86_64"))))] +#[cfg(not(all(feature = "hardware-lock-elision", any(target_arch = "x86", target_arch = "x86_64"))))] impl AtomicElisionExt for AtomicUsize { type IntType = usize; @@ -48,37 +50,33 @@ } } -#[cfg(all(feature = "nightly", any(target_arch = "x86", target_arch = "x86_64")))] +#[cfg(all(feature = "hardware-lock-elision", 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 { unsafe { + use core::arch::asm; let prev: usize; - 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 { - unsafe { - let prev: usize; - llvm_asm!("xacquire; lock; cmpxchgq $2, $1" - : "={rax}" (prev), "+*m" (self) - : "r" (new), "{rax}" (current) - : "memory" - : "volatile"); + #[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, + ); if prev == current { Ok(prev) } else { @@ -87,29 +85,27 @@ } } - #[cfg(target_pointer_width = "32")] - #[inline] - fn elision_fetch_sub_release(&self, val: usize) -> usize { - unsafe { - let prev: usize; - 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 { + use core::arch::asm; let prev: usize; - llvm_asm!("xrelease; lock; xaddq $2, $1" - : "=r" (prev), "+*m" (self) - : "0" (val.wrapping_neg()) - : "memory" - : "volatile"); + #[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, + ); prev } } diff -Nru rust-parking-lot-0.11.2/src/fair_mutex.rs rust-parking-lot-0.12.1/src/fair_mutex.rs --- rust-parking-lot-0.11.2/src/fair_mutex.rs 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/src/fair_mutex.rs 1973-11-29 21:33:09.000000000 +0000 @@ -11,24 +11,21 @@ /// 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 also be statically initialized or created via a `new` +/// mutex can be statically initialized or created by the `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 locking fairness +/// The regular mutex provided by `parking_lot` uses eventual fairness /// (after some time it will default to the fair algorithm), but eventual -/// 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 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. +/// fairness does not provide the same guarantees an always fair method would. +/// Fair mutexes are generally slower, but sometimes needed. +/// +/// 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. /// /// A fair mutex may not be interesting if threads have different priorities (this is known as /// priority inversion). @@ -38,7 +35,7 @@ /// - No poisoning, the lock is released normally on panic. /// - Only requires 1 byte of space, whereas the standard library boxes the /// `FairMutex` due to platform limitations. -/// - Can be statically constructed (requires the `const_fn` nightly feature). +/// - Can be statically constructed. /// - Does not require any drop glue when dropped. /// - Inline fast path for the uncontended case. /// - Efficient handling of micro-contention using adaptive spinning. diff -Nru rust-parking-lot-0.11.2/src/lib.rs rust-parking-lot-0.12.1/src/lib.rs --- rust-parking-lot-0.11.2/src/lib.rs 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/src/lib.rs 1973-11-29 21:33:09.000000000 +0000 @@ -11,7 +11,6 @@ #![warn(missing_docs)] #![warn(rust_2018_idioms)] -#![cfg_attr(feature = "nightly", feature(llvm_asm))] mod condvar; mod elision; diff -Nru rust-parking-lot-0.11.2/src/mutex.rs rust-parking-lot-0.12.1/src/mutex.rs --- rust-parking-lot-0.11.2/src/mutex.rs 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/src/mutex.rs 1973-11-29 21:33:09.000000000 +0000 @@ -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 also be statically initialized or created via a `new` +/// mutex can be statically initialized or created by the `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 @@ -42,7 +42,7 @@ /// - No poisoning, the lock is released normally on panic. /// - Only requires 1 byte of space, whereas the standard library boxes the /// `Mutex` due to platform limitations. -/// - Can be statically constructed (requires the `const_fn` nightly feature). +/// - Can be statically constructed. /// - Does not require any drop glue when dropped. /// - Inline fast path for the uncontended case. /// - Efficient handling of micro-contention using adaptive spinning. diff -Nru rust-parking-lot-0.11.2/src/once.rs rust-parking-lot-0.12.1/src/once.rs --- rust-parking-lot-0.11.2/src/once.rs 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/src/once.rs 1973-11-29 21:33:09.000000000 +0000 @@ -258,11 +258,11 @@ // Park our thread until we are woken up by the thread that owns the // lock. + let addr = self as *const _ as usize; + let validate = || self.0.load(Ordering::Relaxed) == LOCKED_BIT | PARKED_BIT; + let before_sleep = || {}; + let timed_out = |_, _| unreachable!(); unsafe { - let addr = self as *const _ as usize; - let validate = || self.0.load(Ordering::Relaxed) == LOCKED_BIT | PARKED_BIT; - let before_sleep = || {}; - let timed_out = |_, _| unreachable!(); parking_lot_core::park( addr, validate, @@ -285,8 +285,8 @@ let once = self.0; let state = once.0.swap(POISON_BIT, Ordering::Release); if state & PARKED_BIT != 0 { + let addr = once as *const _ as usize; unsafe { - let addr = once as *const _ as usize; parking_lot_core::unpark_all(addr, DEFAULT_UNPARK_TOKEN); } } @@ -307,8 +307,8 @@ // Now unlock the state, set the done bit and unpark all threads let state = self.0.swap(DONE_BIT, Ordering::Release); if state & PARKED_BIT != 0 { + let addr = self as *const _ as usize; unsafe { - let addr = self as *const _ as usize; parking_lot_core::unpark_all(addr, DEFAULT_UNPARK_TOKEN); } } diff -Nru rust-parking-lot-0.11.2/src/raw_mutex.rs rust-parking-lot-0.12.1/src/raw_mutex.rs --- rust-parking-lot-0.11.2/src/raw_mutex.rs 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/src/raw_mutex.rs 1973-11-29 21:33:09.000000000 +0000 @@ -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 -Nru rust-parking-lot-0.11.2/src/raw_rwlock.rs rust-parking-lot-0.12.1/src/raw_rwlock.rs --- rust-parking-lot-0.11.2/src/raw_rwlock.rs 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/src/raw_rwlock.rs 1973-11-29 21:33:09.000000000 +0000 @@ -12,12 +12,11 @@ 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; +use std::time::{Duration, Instant}; // 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 @@ -144,6 +143,12 @@ 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 { @@ -983,8 +988,8 @@ if let Err(x) = self.state.compare_exchange_weak( state, state | WRITER_PARKED_BIT, - Ordering::Relaxed, - Ordering::Relaxed, + Ordering::Acquire, + Ordering::Acquire, ) { state = x; continue; diff -Nru rust-parking-lot-0.11.2/src/rwlock.rs rust-parking-lot-0.12.1/src/rwlock.rs --- rust-parking-lot-0.11.2/src/rwlock.rs 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/src/rwlock.rs 1973-11-29 21:33:09.000000000 +0000 @@ -55,7 +55,7 @@ /// - No poisoning, the lock is released normally on panic. /// - Only requires 1 word of space, whereas the standard library boxes the /// `RwLock` due to platform limitations. -/// - Can be statically constructed (requires the `const_fn` nightly feature). +/// - Can be statically constructed. /// - Does not require any drop glue when dropped. /// - Inline fast path for the uncontended case. /// - Efficient handling of micro-contention using adaptive spinning. @@ -408,6 +408,8 @@ 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); } @@ -419,6 +421,8 @@ 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); } @@ -430,6 +434,8 @@ 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); } @@ -615,4 +621,22 @@ .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 -Nru rust-parking-lot-0.11.2/src/util.rs rust-parking-lot-0.12.1/src/util.rs --- rust-parking-lot-0.11.2/src/util.rs 1973-11-29 21:33:09.000000000 +0000 +++ rust-parking-lot-0.12.1/src/util.rs 1973-11-29 21:33:09.000000000 +0000 @@ -5,8 +5,7 @@ // http://opensource.org/licenses/MIT>, at your option. This file may not be // copied, modified, or distributed except according to those terms. -use instant::Instant; -use std::time::Duration; +use std::time::{Duration, Instant}; // Option::unchecked_unwrap pub trait UncheckedOptionExt {