aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 01:02:37 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 01:02:37 +0000
commitfa9f0b496b6b0bdf3671390d09a94d5b3ba9ec38 (patch)
tree8555918e06cc10c545d628a5e93547bd5a24af54
parent48c8cb383e7ad7fb9e1f9c0f845230411f016b5b (diff)
parent37d9c53d0030a7db063c91d388e55a3ff4fd1c40 (diff)
downloadcrossbeam-epoch-android14-mainline-cellbroadcast-release.tar.gz
Change-Id: I154c3e639637784dc1e54221f6f40685bb651e41
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp15
-rw-r--r--CHANGELOG.md44
-rw-r--r--Cargo.lock249
-rw-r--r--Cargo.toml29
-rw-r--r--Cargo.toml.orig26
-rw-r--r--METADATA12
-rw-r--r--README.md4
-rw-r--r--TEST_MAPPING3
-rw-r--r--build-common.rs13
-rw-r--r--build.rs26
-rw-r--r--no_atomic.rs16
-rw-r--r--src/atomic.rs118
-rw-r--r--src/collector.rs6
-rw-r--r--src/default.rs30
-rw-r--r--src/deferred.rs19
-rw-r--r--src/guard.rs6
-rw-r--r--src/internal.rs109
-rw-r--r--src/lib.rs21
-rw-r--r--src/sync/mod.rs3
-rw-r--r--src/sync/once_lock.rs103
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
diff --git a/Android.bp b/Android.bp
index bd3c978..a05ed8f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -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.
diff --git a/Cargo.lock b/Cargo.lock
index ded699e..dab6b89 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index abacbe2..0ba7985 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"
diff --git a/METADATA b/METADATA
index 1377873..07adda6 100644
--- a/METADATA
+++ b/METADATA
@@ -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
}
}
diff --git a/README.md b/README.md
index eb33bad..2840ea7 100644
--- a/README.md
+++ b/README.md
@@ -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("-")
+}
diff --git a/build.rs b/build.rs
index 587e058..978141a 100644
--- a/build.rs
+++ b/build.rs
@@ -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.
//
diff --git a/src/lib.rs b/src/lib.rs
index ba1d331..b432c1f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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() };
+ }
+ }
+}