diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 01:02:37 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2023-07-07 01:02:37 +0000 |
commit | fa9f0b496b6b0bdf3671390d09a94d5b3ba9ec38 (patch) | |
tree | 8555918e06cc10c545d628a5e93547bd5a24af54 | |
parent | 48c8cb383e7ad7fb9e1f9c0f845230411f016b5b (diff) | |
parent | 37d9c53d0030a7db063c91d388e55a3ff4fd1c40 (diff) | |
download | crossbeam-epoch-aml_cbr_341011000.tar.gz |
Snap for 10447354 from 37d9c53d0030a7db063c91d388e55a3ff4fd1c40 to mainline-cellbroadcast-releaseaml_cbr_341710000aml_cbr_341610000aml_cbr_341510010aml_cbr_341410010aml_cbr_341311010aml_cbr_341110000aml_cbr_341011000aml_cbr_340914000android14-mainline-cellbroadcast-release
Change-Id: I154c3e639637784dc1e54221f6f40685bb651e41
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 15 | ||||
-rw-r--r-- | CHANGELOG.md | 44 | ||||
-rw-r--r-- | Cargo.lock | 249 | ||||
-rw-r--r-- | Cargo.toml | 29 | ||||
-rw-r--r-- | Cargo.toml.orig | 26 | ||||
-rw-r--r-- | METADATA | 12 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | TEST_MAPPING | 3 | ||||
-rw-r--r-- | build-common.rs | 13 | ||||
-rw-r--r-- | build.rs | 26 | ||||
-rw-r--r-- | no_atomic.rs | 16 | ||||
-rw-r--r-- | src/atomic.rs | 118 | ||||
-rw-r--r-- | src/collector.rs | 6 | ||||
-rw-r--r-- | src/default.rs | 30 | ||||
-rw-r--r-- | src/deferred.rs | 19 | ||||
-rw-r--r-- | src/guard.rs | 6 | ||||
-rw-r--r-- | src/internal.rs | 109 | ||||
-rw-r--r-- | src/lib.rs | 21 | ||||
-rw-r--r-- | src/sync/mod.rs | 3 | ||||
-rw-r--r-- | src/sync/once_lock.rs | 103 |
21 files changed, 577 insertions, 277 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 0a948d5..fdc8b14 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,6 +1,6 @@ { "git": { - "sha1": "2988f873f87d2263a7fd2b9465fb9c28f43a6490" + "sha1": "721382b00b5dadd81954ed66764d547e2f1bb7a3" }, "path_in_vcs": "crossbeam-epoch" }
\ No newline at end of file @@ -44,7 +44,7 @@ rust_test { host_supported: true, crate_name: "crossbeam_epoch", cargo_env_compat: true, - cargo_pkg_version: "0.9.7", + cargo_pkg_version: "0.9.14", srcs: ["src/lib.rs"], test_suites: ["general-tests"], auto_gen_config: true, @@ -55,17 +55,16 @@ rust_test { features: [ "alloc", "default", - "lazy_static", "std", ], rustlibs: [ "libcfg_if", "libcrossbeam_utils", - "liblazy_static", "libmemoffset", "librand", "libscopeguard", ], + proc_macros: ["librustversion"], } rust_library { @@ -73,20 +72,24 @@ rust_library { host_supported: true, crate_name: "crossbeam_epoch", cargo_env_compat: true, - cargo_pkg_version: "0.9.7", + cargo_pkg_version: "0.9.14", srcs: ["src/lib.rs"], edition: "2018", features: [ "alloc", "default", - "lazy_static", "std", ], rustlibs: [ "libcfg_if", "libcrossbeam_utils", - "liblazy_static", "libmemoffset", "libscopeguard", ], + apex_available: [ + "//apex_available:platform", + "//apex_available:anyapex", + ], + product_available: true, + vendor_available: true, } diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c158f6..f7508ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ +# Version 0.9.14 + +- Update `memoffset` to 0.8. (#955) + +# Version 0.9.13 + +- Fix build script bug introduced in 0.9.12. (#932) + +# Version 0.9.12 + +**Note:** This release has been yanked due to regression fixed in 0.9.13. + +- Update `memoffset` to 0.7. (#926) +- Improve support for custom targets. (#922) + +# Version 0.9.11 + +- Removes the dependency on the `once_cell` crate to restore the MSRV. (#913) +- Work around [rust-lang#98302](https://github.com/rust-lang/rust/issues/98302), which causes compile error on windows-gnu when LTO is enabled. (#913) + +# Version 0.9.10 + +- Bump the minimum supported Rust version to 1.38. (#877) +- Mitigate the risk of segmentation faults in buggy downstream implementations. (#879) +- Add `{Atomic, Shared}::try_into_owned` (#701) + +# Version 0.9.9 + +- Replace lazy_static with once_cell. (#817) + +# Version 0.9.8 + +- Make `Atomic::null()` const function at 1.61+. (#797) + # Version 0.9.7 - Fix Miri error when `-Zmiri-check-number-validity` is enabled. (#779) @@ -14,15 +48,21 @@ # Version 0.9.4 +**Note**: This release has been yanked. See [#693](https://github.com/crossbeam-rs/crossbeam/issues/693) for details. + - Fix UB in `<[MaybeUninit<T>] as Pointable>::init` when global allocator failed allocation. (#690) - Bump `loom` dependency to version 0.5. (#686) # Version 0.9.3 +**Note**: This release has been yanked. See [#693](https://github.com/crossbeam-rs/crossbeam/issues/693) for details. + - Make `loom` dependency optional. (#666) # Version 0.9.2 +**Note**: This release has been yanked. See [#693](https://github.com/crossbeam-rs/crossbeam/issues/693) for details. + - Add `Atomic::compare_exchange` and `Atomic::compare_exchange_weak`. (#628) - Deprecate `Atomic::compare_and_set` and `Atomic::compare_and_set_weak`. Use `Atomic::compare_exchange` or `Atomic::compare_exchange_weak` instead. (#628) - Make `const_fn` dependency optional. (#611) @@ -30,10 +70,14 @@ # Version 0.9.1 +**Note**: This release has been yanked. See [#693](https://github.com/crossbeam-rs/crossbeam/issues/693) for details. + - Bump `memoffset` dependency to version 0.6. (#592) # Version 0.9.0 +**Note**: This release has been yanked. See [#693](https://github.com/crossbeam-rs/crossbeam/issues/693) for details. + - Bump the minimum supported Rust version to 1.36. - Support dynamically sized types. @@ -3,25 +3,16 @@ version = 3 [[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - -[[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "cc" -version = "1.0.72" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -30,54 +21,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "const_fn" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" - -[[package]] name = "crossbeam-epoch" -version = "0.9.7" +version = "0.9.14" dependencies = [ + "autocfg", "cfg-if", - "const_fn", "crossbeam-utils", - "lazy_static", "loom", "memoffset", "rand", + "rustversion", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.7" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", - "lazy_static", "loom", ] [[package]] name = "generator" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1d9279ca822891c1a4dae06d185612cf8fc6acfe5dff37781b41297811b12ee" +checksum = "33a20a288a94683f5f4da0adecdbe095c94a77c295e514cc6484e9394dd8376e" dependencies = [ "cc", "libc", "log", "rustversion", - "winapi", + "windows", ] [[package]] name = "getrandom" -version = "0.2.4" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418d37c8b1d42553c93648be529cb70f920d3baf8ef469b74b9638df426e0b4c" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", @@ -92,24 +76,24 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.117" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] [[package]] name = "loom" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc5c7d328e32cc4954e8e01193d7f0ef5ab257b5090b70a964e099a36034309" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" dependencies = [ "cfg-if", "generator", @@ -129,59 +113,74 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] name = "once_cell" -version = "1.9.0" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "overload" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "pin-project-lite" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.15" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", "rand_core", - "rand_hc", ] [[package]] @@ -196,27 +195,18 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", ] [[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - -[[package]] name = "regex" -version = "1.5.4" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ "regex-syntax", ] @@ -232,21 +222,21 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "rustversion" -version = "1.0.6" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" [[package]] name = "scoped-tls" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" @@ -265,35 +255,36 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "syn" -version = "1.0.86" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if", "once_cell", ] [[package]] name = "tracing" -version = "0.1.30" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d8d93354fe2a8e50d5953f5ae2e47a3fc2ef03292e7ea46e3cc38f549525fb9" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", @@ -303,9 +294,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.19" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8276d9a4a3a558d7b7ad5303ad50b53d58264641b82914b7ada36bd762e7a716" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", @@ -314,19 +305,19 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.22" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03cfcb51380632a72d3111cb8d3447a8d908e577d31beeac006f836383d29a23" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ - "lazy_static", + "once_cell", "valuable", ] [[package]] name = "tracing-log" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" dependencies = [ "lazy_static", "log", @@ -335,13 +326,13 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.8" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74786ce43333fcf51efe947aed9718fbe46d5c7328ec3f1029e818083966d9aa" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" dependencies = [ - "ansi_term", - "lazy_static", "matchers", + "nu-ansi-term", + "once_cell", "regex", "sharded-slab", "smallvec", @@ -352,10 +343,10 @@ dependencies = [ ] [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-ident" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "valuable" @@ -365,9 +356,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "winapi" @@ -390,3 +381,69 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" @@ -11,11 +11,12 @@ [package] edition = "2018" -rust-version = "1.36" +rust-version = "1.38" name = "crossbeam-epoch" -version = "0.9.7" +version = "0.9.14" description = "Epoch-based garbage collection" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-epoch" +readme = "README.md" keywords = [ "lock-free", "rcu", @@ -33,28 +34,26 @@ repository = "https://github.com/crossbeam-rs/crossbeam" [dependencies.cfg-if] version = "1" -[dependencies.const_fn] -version = "0.4.4" -optional = true - [dependencies.crossbeam-utils] version = "0.8.5" default-features = false -[dependencies.lazy_static] -version = "1.4.0" -optional = true - [dependencies.memoffset] -version = "0.6" +version = "0.8" [dependencies.scopeguard] -version = "1.1.0" +version = "1.1" default-features = false [dev-dependencies.rand] version = "0.8" +[dev-dependencies.rustversion] +version = "1" + +[build-dependencies.autocfg] +version = "1" + [features] alloc = [] default = ["std"] @@ -62,14 +61,10 @@ loom = [ "loom-crate", "crossbeam-utils/loom", ] -nightly = [ - "crossbeam-utils/nightly", - "const_fn", -] +nightly = ["crossbeam-utils/nightly"] std = [ "alloc", "crossbeam-utils/std", - "lazy_static", ] [target."cfg(crossbeam_loom)".dependencies.loom-crate] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index bdb095a..45428bf 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -4,9 +4,9 @@ name = "crossbeam-epoch" # - Update CHANGELOG.md # - Update README.md # - Create "crossbeam-epoch-X.Y.Z" git tag -version = "0.9.7" +version = "0.9.14" edition = "2018" -rust-version = "1.36" +rust-version = "1.38" license = "MIT OR Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-epoch" @@ -19,7 +19,7 @@ default = ["std"] # Enable to use APIs that require `std`. # This is enabled by default. -std = ["alloc", "crossbeam-utils/std", "lazy_static"] +std = ["alloc", "crossbeam-utils/std"] # Enable to use APIs that require `alloc`. # This is enabled by default and also enabled if the `std` feature is enabled. @@ -27,12 +27,14 @@ std = ["alloc", "crossbeam-utils/std", "lazy_static"] # NOTE: Disabling both `std` *and* `alloc` features is not supported yet. alloc = [] +# These features are no longer used. +# TODO: remove in the next major version. # Enable to use of unstable functionality. # This is disabled by default and requires recent nightly compiler. # # NOTE: This feature is outside of the normal semver guarantees and minor or # patch versions of crossbeam may make breaking changes to them at any time. -nightly = ["crossbeam-utils/nightly", "const_fn"] +nightly = ["crossbeam-utils/nightly"] # Enable the use of loom for concurrency testing. # @@ -40,10 +42,13 @@ nightly = ["crossbeam-utils/nightly", "const_fn"] # patch versions of crossbeam may make breaking changes to them at any time. loom = ["loom-crate", "crossbeam-utils/loom"] +[build-dependencies] +autocfg = "1" + [dependencies] cfg-if = "1" -const_fn = { version = "0.4.4", optional = true } -memoffset = "0.6" +memoffset = "0.8" +scopeguard = { version = "1.1", default-features = false } # Enable the use of loom for concurrency testing. # @@ -57,13 +62,6 @@ version = "0.8.5" path = "../crossbeam-utils" default-features = false -[dependencies.lazy_static] -version = "1.4.0" -optional = true - -[dependencies.scopeguard] -version = "1.1.0" -default-features = false - [dev-dependencies] rand = "0.8" +rustversion = "1" @@ -1,3 +1,7 @@ +# This project was upgraded with external_updater. +# Usage: tools/external_updater/updater.sh update rust/crates/crossbeam-epoch +# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md + name: "crossbeam-epoch" description: "Epoch-based garbage collection" third_party { @@ -7,13 +11,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/crossbeam-epoch/crossbeam-epoch-0.9.7.crate" + value: "https://static.crates.io/crates/crossbeam-epoch/crossbeam-epoch-0.9.14.crate" } - version: "0.9.7" + version: "0.9.14" license_type: NOTICE last_upgrade_date { - year: 2022 + year: 2023 month: 3 - day: 1 + day: 6 } } @@ -8,7 +8,7 @@ https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-epoch#license) https://crates.io/crates/crossbeam-epoch) [![Documentation](https://docs.rs/crossbeam-epoch/badge.svg)]( https://docs.rs/crossbeam-epoch) -[![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-lightgray.svg)]( +[![Rust 1.38+](https://img.shields.io/badge/rust-1.38+-lightgray.svg)]( https://www.rust-lang.org) [![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.com/invite/JXYwgWZ) @@ -35,7 +35,7 @@ crossbeam-epoch = "0.9" Crossbeam Epoch supports stable Rust releases going back at least six months, and every time the minimum supported Rust version is increased, a new minor -version is released. Currently, the minimum supported Rust version is 1.36. +version is released. Currently, the minimum supported Rust version is 1.38. ## License diff --git a/TEST_MAPPING b/TEST_MAPPING index 161921c..5f5ced7 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -8,6 +8,9 @@ "path": "external/rust/crates/crossbeam-deque" }, { + "path": "external/rust/crates/hashbrown" + }, + { "path": "external/rust/crates/tinytemplate" }, { diff --git a/build-common.rs b/build-common.rs new file mode 100644 index 0000000..e91bb4d --- /dev/null +++ b/build-common.rs @@ -0,0 +1,13 @@ +// The target triplets have the form of 'arch-vendor-system'. +// +// When building for Linux (e.g. the 'system' part is +// 'linux-something'), replace the vendor with 'unknown' +// so that mapping to rust standard targets happens correctly. +fn convert_custom_linux_target(target: String) -> String { + let mut parts: Vec<&str> = target.split('-').collect(); + let system = parts.get(2); + if system == Some(&"linux") { + parts[1] = "unknown"; + }; + parts.join("-") +} @@ -15,10 +15,11 @@ use std::env; include!("no_atomic.rs"); +include!("build-common.rs"); fn main() { let target = match env::var("TARGET") { - Ok(target) => target, + Ok(target) => convert_custom_linux_target(target), Err(e) => { println!( "cargo:warning={}: unable to get TARGET environment variable: {}", @@ -29,13 +30,28 @@ fn main() { } }; - // Note that this is `no_*`, not `has_*`. This allows treating - // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't - // run. This is needed for compatibility with non-cargo build systems that - // don't run the build script. + let cfg = match autocfg::AutoCfg::new() { + Ok(cfg) => cfg, + Err(e) => { + println!( + "cargo:warning={}: unable to determine rustc version: {}", + env!("CARGO_PKG_NAME"), + e + ); + return; + } + }; + + // Note that this is `no_`*, not `has_*`. This allows treating as the latest + // stable rustc is used when the build script doesn't run. This is useful + // for non-cargo build systems that don't run the build script. if NO_ATOMIC_CAS.contains(&&*target) { println!("cargo:rustc-cfg=crossbeam_no_atomic_cas"); } + if !cfg.probe_rustc_version(1, 61) { + println!("cargo:rustc-cfg=crossbeam_no_const_fn_trait_bound"); + } + println!("cargo:rerun-if-changed=no_atomic.rs"); } diff --git a/no_atomic.rs b/no_atomic.rs index 90ac60a..beb11b0 100644 --- a/no_atomic.rs +++ b/no_atomic.rs @@ -2,13 +2,17 @@ // It is not intended for manual editing. const NO_ATOMIC_CAS: &[&str] = &[ + "armv4t-none-eabi", + "armv5te-none-eabi", "avr-unknown-gnu-atmega328", "bpfeb-unknown-none", "bpfel-unknown-none", "msp430-none-elf", "riscv32i-unknown-none-elf", + "riscv32im-unknown-none-elf", "riscv32imc-unknown-none-elf", "thumbv4t-none-eabi", + "thumbv5te-none-eabi", "thumbv6m-none-eabi", ]; @@ -17,11 +21,14 @@ const NO_ATOMIC_64: &[&str] = &[ "arm-linux-androideabi", "armebv7r-none-eabi", "armebv7r-none-eabihf", + "armv4t-none-eabi", "armv4t-unknown-linux-gnueabi", + "armv5te-none-eabi", "armv5te-unknown-linux-gnueabi", "armv5te-unknown-linux-musleabi", "armv5te-unknown-linux-uclibceabi", "armv6k-nintendo-3ds", + "armv7-sony-vita-newlibeabihf", "armv7r-none-eabi", "armv7r-none-eabihf", "avr-unknown-gnu-atmega328", @@ -31,6 +38,7 @@ const NO_ATOMIC_64: &[&str] = &[ "mips-unknown-linux-musl", "mips-unknown-linux-uclibc", "mipsel-sony-psp", + "mipsel-sony-psx", "mipsel-unknown-linux-gnu", "mipsel-unknown-linux-musl", "mipsel-unknown-linux-uclibc", @@ -49,10 +57,12 @@ const NO_ATOMIC_64: &[&str] = &[ "riscv32gc-unknown-linux-gnu", "riscv32gc-unknown-linux-musl", "riscv32i-unknown-none-elf", + "riscv32im-unknown-none-elf", "riscv32imac-unknown-none-elf", - "riscv32imc-esp-espidf", + "riscv32imac-unknown-xous-elf", "riscv32imc-unknown-none-elf", "thumbv4t-none-eabi", + "thumbv5te-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabi", "thumbv7em-none-eabihf", @@ -65,7 +75,11 @@ const NO_ATOMIC_64: &[&str] = &[ #[allow(dead_code)] // Only crossbeam-utils uses this. const NO_ATOMIC: &[&str] = &[ "avr-unknown-gnu-atmega328", + "bpfeb-unknown-none", + "bpfel-unknown-none", + "mipsel-sony-psx", "msp430-none-elf", "riscv32i-unknown-none-elf", + "riscv32im-unknown-none-elf", "riscv32imc-unknown-none-elf", ]; diff --git a/src/atomic.rs b/src/atomic.rs index f727387..19bab47 100644 --- a/src/atomic.rs +++ b/src/atomic.rs @@ -252,7 +252,7 @@ impl<T> Pointable for [MaybeUninit<T>] { let size = mem::size_of::<Array<T>>() + mem::size_of::<MaybeUninit<T>>() * len; let align = mem::align_of::<Array<T>>(); let layout = alloc::Layout::from_size_align(size, align).unwrap(); - let ptr = alloc::alloc(layout) as *mut Array<T>; + let ptr = alloc::alloc(layout).cast::<Array<T>>(); if ptr.is_null() { alloc::handle_alloc_error(layout); } @@ -305,6 +305,7 @@ impl<T> Atomic<T> { /// use crossbeam_epoch::Atomic; /// /// let a = Atomic::new(1234); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn new(init: T) -> Atomic<T> { Self::init(init) @@ -320,6 +321,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// use crossbeam_epoch::Atomic; /// /// let a = Atomic::<i32>::init(1234); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn init(init: T::Init) -> Atomic<T> { Self::from(Owned::init(init)) @@ -342,8 +344,16 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// /// let a = Atomic::<i32>::null(); /// ``` - /// - #[cfg_attr(all(feature = "nightly", not(crossbeam_loom)), const_fn::const_fn)] + #[cfg(all(not(crossbeam_no_const_fn_trait_bound), not(crossbeam_loom)))] + pub const fn null() -> Atomic<T> { + Self { + data: AtomicUsize::new(0), + _marker: PhantomData, + } + } + + /// Returns a new null atomic pointer. + #[cfg(not(all(not(crossbeam_no_const_fn_trait_bound), not(crossbeam_loom))))] pub fn null() -> Atomic<T> { Self { data: AtomicUsize::new(0), @@ -365,6 +375,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// let a = Atomic::new(1234); /// let guard = &epoch::pin(); /// let p = a.load(SeqCst, guard); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn load<'g>(&self, ord: Ordering, _: &'g Guard) -> Shared<'g, T> { unsafe { Shared::from_usize(self.data.load(ord)) } @@ -390,6 +401,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// let a = Atomic::new(1234); /// let guard = &epoch::pin(); /// let p = a.load_consume(guard); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn load_consume<'g>(&self, _: &'g Guard) -> Shared<'g, T> { unsafe { Shared::from_usize(self.data.load_consume()) } @@ -407,8 +419,10 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// use std::sync::atomic::Ordering::SeqCst; /// /// let a = Atomic::new(1234); + /// # unsafe { drop(a.load(SeqCst, &crossbeam_epoch::pin()).into_owned()); } // avoid leak /// a.store(Shared::null(), SeqCst); /// a.store(Owned::new(1234), SeqCst); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn store<P: Pointer<T>>(&self, new: P, ord: Ordering) { self.data.store(new.into_usize(), ord); @@ -429,6 +443,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// let a = Atomic::new(1234); /// let guard = &epoch::pin(); /// let p = a.swap(Shared::null(), SeqCst, guard); + /// # unsafe { drop(p.into_owned()); } // avoid leak /// ``` pub fn swap<'g, P: Pointer<T>>(&self, new: P, ord: Ordering, _: &'g Guard) -> Shared<'g, T> { unsafe { Shared::from_usize(self.data.swap(new.into_usize(), ord)) } @@ -463,6 +478,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// let curr = a.load(SeqCst, guard); /// let res1 = a.compare_exchange(curr, Shared::null(), SeqCst, SeqCst, guard); /// let res2 = a.compare_exchange(curr, Owned::new(5678), SeqCst, SeqCst, guard); + /// # unsafe { drop(curr.into_owned()); } // avoid leak /// ``` pub fn compare_exchange<'g, P>( &self, @@ -518,6 +534,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// /// let mut new = Owned::new(5678); /// let mut ptr = a.load(SeqCst, guard); + /// # unsafe { drop(a.load(SeqCst, guard).into_owned()); } // avoid leak /// loop { /// match a.compare_exchange_weak(ptr, new, SeqCst, SeqCst, guard) { /// Ok(p) => { @@ -538,6 +555,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// Err(err) => curr = err.current, /// } /// } + /// # unsafe { drop(curr.into_owned()); } // avoid leak /// ``` pub fn compare_exchange_weak<'g, P>( &self, @@ -600,6 +618,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// /// let res2 = a.fetch_update(SeqCst, SeqCst, guard, |x| None); /// assert!(res2.is_err()); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn fetch_update<'g, F>( &self, @@ -658,6 +677,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// let curr = a.load(SeqCst, guard); /// let res1 = a.compare_and_set(curr, Shared::null(), SeqCst, guard); /// let res2 = a.compare_and_set(curr, Owned::new(5678), SeqCst, guard); + /// # unsafe { drop(curr.into_owned()); } // avoid leak /// ``` // TODO: remove in the next major version. #[allow(deprecated)] @@ -715,6 +735,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// /// let mut new = Owned::new(5678); /// let mut ptr = a.load(SeqCst, guard); + /// # unsafe { drop(a.load(SeqCst, guard).into_owned()); } // avoid leak /// loop { /// match a.compare_and_set_weak(ptr, new, SeqCst, guard) { /// Ok(p) => { @@ -735,6 +756,7 @@ impl<T: ?Sized + Pointable> Atomic<T> { /// Err(err) => curr = err.current, /// } /// } + /// # unsafe { drop(curr.into_owned()); } // avoid leak /// ``` // TODO: remove in the next major version. #[allow(deprecated)] @@ -869,6 +891,52 @@ impl<T: ?Sized + Pointable> Atomic<T> { Owned::from_usize(self.data.into_inner()) } } + + /// Takes ownership of the pointee if it is non-null. + /// + /// This consumes the atomic and converts it into [`Owned`]. As [`Atomic`] doesn't have a + /// destructor and doesn't drop the pointee while [`Owned`] does, this is suitable for + /// destructors of data structures. + /// + /// # Safety + /// + /// This method may be called only if the pointer is valid and nobody else is holding a + /// reference to the same object, or the pointer is null. + /// + /// # Examples + /// + /// ```rust + /// # use std::mem; + /// # use crossbeam_epoch::Atomic; + /// struct DataStructure { + /// ptr: Atomic<usize>, + /// } + /// + /// impl Drop for DataStructure { + /// fn drop(&mut self) { + /// // By now the DataStructure lives only in our thread and we are sure we don't hold + /// // any Shared or & to it ourselves, but it may be null, so we have to be careful. + /// let old = mem::replace(&mut self.ptr, Atomic::null()); + /// unsafe { + /// if let Some(x) = old.try_into_owned() { + /// drop(x) + /// } + /// } + /// } + /// } + /// ``` + pub unsafe fn try_into_owned(self) -> Option<Owned<T>> { + // FIXME: See self.into_owned() + #[cfg(crossbeam_loom)] + let data = self.data.unsync_load(); + #[cfg(not(crossbeam_loom))] + let data = self.data.into_inner(); + if decompose_tag::<T>(data).0 == 0 { + None + } else { + Some(Owned::from_usize(data)) + } + } } impl<T: ?Sized + Pointable> fmt::Debug for Atomic<T> { @@ -917,6 +985,7 @@ impl<T: ?Sized + Pointable> From<Owned<T>> for Atomic<T> { /// use crossbeam_epoch::{Atomic, Owned}; /// /// let a = Atomic::<i32>::from(Owned::new(1234)); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` fn from(owned: Owned<T>) -> Self { let data = owned.data; @@ -1100,6 +1169,7 @@ impl<T: ?Sized + Pointable> Owned<T> { /// let o = Owned::new(1234); /// let guard = &epoch::pin(); /// let p = o.into_shared(guard); + /// # unsafe { drop(p.into_owned()); } // avoid leak /// ``` #[allow(clippy::needless_lifetimes)] pub fn into_shared<'g>(self, _: &'g Guard) -> Shared<'g, T> { @@ -1283,6 +1353,7 @@ impl<'g, T> Shared<'g, T> { /// let guard = &epoch::pin(); /// let p = a.load(SeqCst, guard); /// assert_eq!(p.as_raw(), raw); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn as_raw(&self) -> *const T { let (raw, _) = decompose_tag::<T>(self.data); @@ -1321,6 +1392,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> { /// assert!(a.load(SeqCst, guard).is_null()); /// a.store(Owned::new(1234), SeqCst); /// assert!(!a.load(SeqCst, guard).is_null()); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn is_null(&self) -> bool { let (raw, _) = decompose_tag::<T>(self.data); @@ -1357,6 +1429,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> { /// unsafe { /// assert_eq!(p.deref(), &1234); /// } + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub unsafe fn deref(&self) -> &'g T { let (raw, _) = decompose_tag::<T>(self.data); @@ -1398,6 +1471,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> { /// unsafe { /// assert_eq!(p.deref(), &vec![1, 2, 3, 4, 5]); /// } + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub unsafe fn deref_mut(&mut self) -> &'g mut T { let (raw, _) = decompose_tag::<T>(self.data); @@ -1434,6 +1508,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> { /// unsafe { /// assert_eq!(p.as_ref(), Some(&1234)); /// } + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub unsafe fn as_ref(&self) -> Option<&'g T> { let (raw, _) = decompose_tag::<T>(self.data); @@ -1473,6 +1548,36 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> { Owned::from_usize(self.data) } + /// Takes ownership of the pointee if it is not null. + /// + /// # Safety + /// + /// This method may be called only if the pointer is valid and nobody else is holding a + /// reference to the same object, or if the pointer is null. + /// + /// # Examples + /// + /// ``` + /// use crossbeam_epoch::{self as epoch, Atomic}; + /// use std::sync::atomic::Ordering::SeqCst; + /// + /// let a = Atomic::new(1234); + /// unsafe { + /// let guard = &epoch::unprotected(); + /// let p = a.load(SeqCst, guard); + /// if let Some(x) = p.try_into_owned() { + /// drop(x); + /// } + /// } + /// ``` + pub unsafe fn try_into_owned(self) -> Option<Owned<T>> { + if self.is_null() { + None + } else { + Some(Owned::from_usize(self.data)) + } + } + /// Returns the tag stored within the pointer. /// /// # Examples @@ -1485,6 +1590,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> { /// let guard = &epoch::pin(); /// let p = a.load(SeqCst, guard); /// assert_eq!(p.tag(), 2); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn tag(&self) -> usize { let (_, tag) = decompose_tag::<T>(self.data); @@ -1508,6 +1614,7 @@ impl<'g, T: ?Sized + Pointable> Shared<'g, T> { /// assert_eq!(p1.tag(), 0); /// assert_eq!(p2.tag(), 2); /// assert_eq!(p1.as_raw(), p2.as_raw()); + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn with_tag(&self, tag: usize) -> Shared<'g, T> { unsafe { Self::from_usize(compose_tag::<T>(self.data, tag)) } @@ -1528,6 +1635,7 @@ impl<T> From<*const T> for Shared<'_, T> { /// /// let p = Shared::from(Box::into_raw(Box::new(1234)) as *const _); /// assert!(!p.is_null()); + /// # unsafe { drop(p.into_owned()); } // avoid leak /// ``` fn from(raw: *const T) -> Self { let raw = raw as usize; @@ -1594,7 +1702,7 @@ mod tests { Shared::<i64>::null().with_tag(7); } - #[cfg(feature = "nightly")] + #[rustversion::since(1.61)] #[test] fn const_atomic_null() { use super::Atomic; @@ -1604,7 +1712,7 @@ mod tests { #[test] fn array_init() { let owned = Owned::<[MaybeUninit<usize>]>::init(10); - let arr: &[MaybeUninit<usize>] = &*owned; + let arr: &[MaybeUninit<usize>] = &owned; assert_eq!(arr.len(), 10); } } diff --git a/src/collector.rs b/src/collector.rs index 099a2ff..5b08511 100644 --- a/src/collector.rs +++ b/src/collector.rs @@ -111,7 +111,7 @@ impl fmt::Debug for LocalHandle { #[cfg(all(test, not(crossbeam_loom)))] mod tests { - use std::mem; + use std::mem::ManuallyDrop; use std::sync::atomic::{AtomicUsize, Ordering}; use crossbeam_utils::thread; @@ -402,15 +402,13 @@ mod tests { v.push(i as i32); } - let ptr = v.as_mut_ptr() as usize; let len = v.len(); + let ptr = ManuallyDrop::new(v).as_mut_ptr() as usize; guard.defer_unchecked(move || { drop(Vec::from_raw_parts(ptr as *const i32 as *mut i32, len, len)); DESTROYS.fetch_add(len, Ordering::Relaxed); }); guard.flush(); - - mem::forget(v); } while DESTROYS.load(Ordering::Relaxed) < COUNT { diff --git a/src/default.rs b/src/default.rs index b7797ce..b42c1c7 100644 --- a/src/default.rs +++ b/src/default.rs @@ -6,16 +6,32 @@ use crate::collector::{Collector, LocalHandle}; use crate::guard::Guard; -use crate::primitive::{lazy_static, thread_local}; +use crate::primitive::thread_local; +#[cfg(not(crossbeam_loom))] +use crate::sync::once_lock::OnceLock; -lazy_static! { - /// The global data for the default garbage collector. - static ref COLLECTOR: Collector = Collector::new(); +fn collector() -> &'static Collector { + #[cfg(not(crossbeam_loom))] + { + /// The global data for the default garbage collector. + static COLLECTOR: OnceLock<Collector> = OnceLock::new(); + COLLECTOR.get_or_init(Collector::new) + } + // FIXME: loom does not currently provide the equivalent of Lazy: + // https://github.com/tokio-rs/loom/issues/263 + #[cfg(crossbeam_loom)] + { + loom::lazy_static! { + /// The global data for the default garbage collector. + static ref COLLECTOR: Collector = Collector::new(); + } + &COLLECTOR + } } thread_local! { /// The per-thread participant for the default garbage collector. - static HANDLE: LocalHandle = COLLECTOR.register(); + static HANDLE: LocalHandle = collector().register(); } /// Pins the current thread. @@ -32,7 +48,7 @@ pub fn is_pinned() -> bool { /// Returns the default global collector. pub fn default_collector() -> &'static Collector { - &COLLECTOR + collector() } #[inline] @@ -42,7 +58,7 @@ where { HANDLE .try_with(|h| f(h)) - .unwrap_or_else(|_| f(&COLLECTOR.register())) + .unwrap_or_else(|_| f(&collector().register())) } #[cfg(all(test, not(crossbeam_loom)))] diff --git a/src/deferred.rs b/src/deferred.rs index c33d515..2f3d79f 100644 --- a/src/deferred.rs +++ b/src/deferred.rs @@ -29,6 +29,15 @@ impl fmt::Debug for Deferred { } impl Deferred { + pub(crate) const NO_OP: Self = { + fn no_op_call(_raw: *mut u8) {} + Self { + call: no_op_call, + data: MaybeUninit::uninit(), + _marker: PhantomData, + } + }; + /// Constructs a new `Deferred` from a `FnOnce()`. pub(crate) fn new<F: FnOnce()>(f: F) -> Self { let size = mem::size_of::<F>(); @@ -37,10 +46,10 @@ impl Deferred { unsafe { if size <= mem::size_of::<Data>() && align <= mem::align_of::<Data>() { let mut data = MaybeUninit::<Data>::uninit(); - ptr::write(data.as_mut_ptr() as *mut F, f); + ptr::write(data.as_mut_ptr().cast::<F>(), f); unsafe fn call<F: FnOnce()>(raw: *mut u8) { - let f: F = ptr::read(raw as *mut F); + let f: F = ptr::read(raw.cast::<F>()); f(); } @@ -52,12 +61,12 @@ impl Deferred { } else { let b: Box<F> = Box::new(f); let mut data = MaybeUninit::<Data>::uninit(); - ptr::write(data.as_mut_ptr() as *mut Box<F>, b); + ptr::write(data.as_mut_ptr().cast::<Box<F>>(), b); unsafe fn call<F: FnOnce()>(raw: *mut u8) { // It's safe to cast `raw` from `*mut u8` to `*mut Box<F>`, because `raw` is // originally derived from `*mut Box<F>`. - let b: Box<F> = ptr::read(raw as *mut Box<F>); + let b: Box<F> = ptr::read(raw.cast::<Box<F>>()); (*b)(); } @@ -74,7 +83,7 @@ impl Deferred { #[inline] pub(crate) fn call(mut self) { let call = self.call; - unsafe { call(self.data.as_mut_ptr() as *mut u8) }; + unsafe { call(self.data.as_mut_ptr().cast::<u8>()) }; } } diff --git a/src/guard.rs b/src/guard.rs index 6db3750..ba7fe1b 100644 --- a/src/guard.rs +++ b/src/guard.rs @@ -46,6 +46,7 @@ use crate::internal::Local; /// if let Some(num) = unsafe { p.as_ref() } { /// println!("The number is {}.", num); /// } +/// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` /// /// # Multiple guards @@ -184,6 +185,7 @@ impl Guard { /// }); /// } /// } + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub unsafe fn defer_unchecked<F, R>(&self, f: F) where @@ -263,6 +265,7 @@ impl Guard { /// guard.defer_destroy(p); /// } /// } + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub unsafe fn defer_destroy<T>(&self, ptr: Shared<'_, T>) { self.defer_unchecked(move || ptr.into_owned()); @@ -320,6 +323,7 @@ impl Guard { /// let p = a.load(SeqCst, &guard); /// assert_eq!(unsafe { p.as_ref() }, Some(&777)); /// } + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn repin(&mut self) { if let Some(local) = unsafe { self.local.as_ref() } { @@ -356,6 +360,7 @@ impl Guard { /// let p = a.load(SeqCst, &guard); /// assert_eq!(unsafe { p.as_ref() }, Some(&777)); /// } + /// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` pub fn repin_after<F, R>(&mut self, f: F) -> R where @@ -451,6 +456,7 @@ impl fmt::Debug for Guard { /// /// // Dropping `dummy` doesn't affect the current thread - it's just a noop. /// } +/// # unsafe { drop(a.into_owned()); } // avoid leak /// ``` /// /// The most common use of this function is when constructing or destructing a data structure. diff --git a/src/internal.rs b/src/internal.rs index de208b1..00c66a4 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -55,9 +55,10 @@ use crate::sync::list::{Entry, IsElement, IterError, List}; use crate::sync::queue::Queue; /// Maximum number of objects a bag can contain. -#[cfg(not(crossbeam_sanitize))] -const MAX_OBJECTS: usize = 62; -#[cfg(crossbeam_sanitize)] +#[cfg(not(any(crossbeam_sanitize, miri)))] +const MAX_OBJECTS: usize = 64; +// Makes it more likely to trigger any potential data races. +#[cfg(any(crossbeam_sanitize, miri))] const MAX_OBJECTS: usize = 4; /// A bag of deferred functions. @@ -106,87 +107,11 @@ impl Bag { } impl Default for Bag { - #[rustfmt::skip] fn default() -> Self { - // TODO: [no_op; MAX_OBJECTS] syntax blocked by https://github.com/rust-lang/rust/issues/49147 - #[cfg(not(crossbeam_sanitize))] - return Bag { + Bag { len: 0, - deferreds: [ - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - ], - }; - #[cfg(crossbeam_sanitize)] - return Bag { - len: 0, - deferreds: [ - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - Deferred::new(no_op_func), - ], - }; + deferreds: [Deferred::NO_OP; MAX_OBJECTS], + } } } @@ -194,7 +119,7 @@ impl Drop for Bag { fn drop(&mut self) { // Call all deferred functions. for deferred in &mut self.deferreds[..self.len] { - let no_op = Deferred::new(no_op_func); + let no_op = Deferred::NO_OP; let owned_deferred = mem::replace(deferred, no_op); owned_deferred.call(); } @@ -210,8 +135,6 @@ impl fmt::Debug for Bag { } } -fn no_op_func() {} - /// A pair of an epoch and a bag. #[derive(Default, Debug)] struct SealedBag { @@ -375,13 +298,14 @@ pub(crate) struct Local { // Make sure `Local` is less than or equal to 2048 bytes. // https://github.com/crossbeam-rs/crossbeam/issues/551 -#[cfg(not(crossbeam_sanitize))] // `crossbeam_sanitize` reduces the size of `Local` +#[cfg(not(any(crossbeam_sanitize, miri)))] // `crossbeam_sanitize` and `miri` reduce the size of `Local` #[test] fn local_size() { - assert!( - core::mem::size_of::<Local>() <= 2048, - "An allocation of `Local` should be <= 2048 bytes." - ); + // TODO: https://github.com/crossbeam-rs/crossbeam/issues/869 + // assert!( + // core::mem::size_of::<Local>() <= 2048, + // "An allocation of `Local` should be <= 2048 bytes." + // ); } impl Local { @@ -468,7 +392,10 @@ impl Local { // Now we must store `new_epoch` into `self.epoch` and execute a `SeqCst` fence. // The fence makes sure that any future loads from `Atomic`s will not happen before // this store. - if cfg!(any(target_arch = "x86", target_arch = "x86_64")) { + if cfg!(all( + any(target_arch = "x86", target_arch = "x86_64"), + not(miri) + )) { // HACK(stjepang): On x86 architectures there are two different ways of executing // a `SeqCst` fence. // @@ -62,7 +62,6 @@ unreachable_pub )] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(const_fn_trait_bound))] #[cfg(crossbeam_loom)] extern crate loom_crate as loom; @@ -78,19 +77,7 @@ mod primitive { pub(crate) mod sync { pub(crate) mod atomic { use core::sync::atomic::Ordering; - pub(crate) use loom::sync::atomic::AtomicUsize; - pub(crate) fn fence(ord: Ordering) { - if let Ordering::Acquire = ord { - } else { - // FIXME: loom only supports acquire fences at the moment. - // https://github.com/tokio-rs/loom/issues/117 - // let's at least not panic... - // this may generate some false positives (`SeqCst` is stronger than `Acquire` - // for example), and some false negatives (`Relaxed` is weaker than `Acquire`), - // but it's the best we can do for the time being. - } - loom::sync::atomic::fence(Ordering::Acquire) - } + pub(crate) use loom::sync::atomic::{fence, AtomicUsize}; // FIXME: loom does not support compiler_fence at the moment. // https://github.com/tokio-rs/loom/issues/117 @@ -101,7 +88,6 @@ mod primitive { } pub(crate) use loom::sync::Arc; } - pub(crate) use loom::lazy_static; pub(crate) use loom::thread_local; } #[cfg(not(crossbeam_no_atomic_cas))] @@ -121,7 +107,7 @@ mod primitive { // https://github.com/tokio-rs/loom#handling-loom-api-differences impl<T> UnsafeCell<T> { #[inline] - pub(crate) fn new(data: T) -> UnsafeCell<T> { + pub(crate) const fn new(data: T) -> UnsafeCell<T> { UnsafeCell(::core::cell::UnsafeCell::new(data)) } @@ -148,9 +134,6 @@ mod primitive { #[cfg(feature = "std")] pub(crate) use std::thread_local; - - #[cfg(feature = "std")] - pub(crate) use lazy_static::lazy_static; } #[cfg(not(crossbeam_no_atomic_cas))] diff --git a/src/sync/mod.rs b/src/sync/mod.rs index 5c06e76..08981be 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -1,4 +1,7 @@ //! Synchronization primitives. pub(crate) mod list; +#[cfg(feature = "std")] +#[cfg(not(crossbeam_loom))] +pub(crate) mod once_lock; pub(crate) mod queue; diff --git a/src/sync/once_lock.rs b/src/sync/once_lock.rs new file mode 100644 index 0000000..c1fefc9 --- /dev/null +++ b/src/sync/once_lock.rs @@ -0,0 +1,103 @@ +// Based on unstable std::sync::OnceLock. +// +// Source: https://github.com/rust-lang/rust/blob/8e9c93df464b7ada3fc7a1c8ccddd9dcb24ee0a0/library/std/src/sync/once_lock.rs + +use core::cell::UnsafeCell; +use core::mem::MaybeUninit; +use core::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Once; + +pub(crate) struct OnceLock<T> { + once: Once, + // Once::is_completed requires Rust 1.43, so use this to track of whether they have been initialized. + is_initialized: AtomicBool, + value: UnsafeCell<MaybeUninit<T>>, + // Unlike std::sync::OnceLock, we don't need PhantomData here because + // we don't use #[may_dangle]. +} + +unsafe impl<T: Sync + Send> Sync for OnceLock<T> {} +unsafe impl<T: Send> Send for OnceLock<T> {} + +impl<T> OnceLock<T> { + /// Creates a new empty cell. + #[must_use] + pub(crate) const fn new() -> Self { + Self { + once: Once::new(), + is_initialized: AtomicBool::new(false), + value: UnsafeCell::new(MaybeUninit::uninit()), + } + } + + /// Gets the contents of the cell, initializing it with `f` if the cell + /// was empty. + /// + /// Many threads may call `get_or_init` concurrently with different + /// initializing functions, but it is guaranteed that only one function + /// will be executed. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and the cell + /// remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. The + /// exact outcome is unspecified. Current implementation deadlocks, but + /// this may be changed to a panic in the future. + pub(crate) fn get_or_init<F>(&self, f: F) -> &T + where + F: FnOnce() -> T, + { + // Fast path check + if self.is_initialized() { + // SAFETY: The inner value has been initialized + return unsafe { self.get_unchecked() }; + } + self.initialize(f); + + debug_assert!(self.is_initialized()); + + // SAFETY: The inner value has been initialized + unsafe { self.get_unchecked() } + } + + #[inline] + fn is_initialized(&self) -> bool { + self.is_initialized.load(Ordering::Acquire) + } + + #[cold] + fn initialize<F>(&self, f: F) + where + F: FnOnce() -> T, + { + let slot = self.value.get().cast::<T>(); + let is_initialized = &self.is_initialized; + + self.once.call_once(|| { + let value = f(); + unsafe { + slot.write(value); + } + is_initialized.store(true, Ordering::Release); + }); + } + + /// # Safety + /// + /// The value must be initialized + unsafe fn get_unchecked(&self) -> &T { + debug_assert!(self.is_initialized()); + &*self.value.get().cast::<T>() + } +} + +impl<T> Drop for OnceLock<T> { + fn drop(&mut self) { + if self.is_initialized() { + // SAFETY: The inner value has been initialized + unsafe { self.value.get().cast::<T>().drop_in_place() }; + } + } +} |