diff --git a/Cargo.lock b/Cargo.lock index 9485e1674448eac3473f22bd65174768064caa47..6d9e18e6488dadbd03e3cc78bb1e8529b84a5f3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,10 +217,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "autocfg" -version = "0.1.6" - [[package]] name = "autocfg" version = "1.0.1" @@ -363,7 +359,7 @@ version = "0.1.0" dependencies = [ "bits_client", "comedy", - "crossbeam-utils 0.8.1", + "crossbeam-utils 0.8.5", "libc", "log", "moz_task", @@ -434,7 +430,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e3ff9db740167616e528c509b3618046fc05d337f8f3182d300f4aa977d2bb" dependencies = [ - "crossbeam-utils 0.8.1", + "crossbeam-utils 0.8.5", "jobserver", "num_cpus", ] @@ -521,7 +517,7 @@ version = "0.0.1" dependencies = [ "base64 0.10.1", "byteorder", - "crossbeam-utils 0.8.1", + "crossbeam-utils 0.8.5", "cstr", "log", "malloc_size_of_derive", @@ -863,40 +859,42 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" dependencies = [ - "crossbeam-utils 0.7.0", + "crossbeam-utils 0.7.2", "maybe-uninit", ] [[package]] name = "crossbeam-channel" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.1", + "crossbeam-utils 0.8.5", ] [[package]] name = "crossbeam-deque" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" +checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" dependencies = [ "crossbeam-epoch", - "crossbeam-utils 0.7.0", + "crossbeam-utils 0.7.2", + "maybe-uninit", ] [[package]] name = "crossbeam-epoch" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" dependencies = [ - "autocfg 0.1.6", + "autocfg", "cfg-if 0.1.10", - "crossbeam-utils 0.7.0", + "crossbeam-utils 0.7.2", "lazy_static", + "maybe-uninit", "memoffset", "scopeguard", ] @@ -907,14 +905,14 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" dependencies = [ - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.6.6", ] [[package]] name = "crossbeam-utils" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" +checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" dependencies = [ "cfg-if 0.1.10", "lazy_static", @@ -922,22 +920,21 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" dependencies = [ - "autocfg 0.1.6", + "autocfg", "cfg-if 0.1.10", "lazy_static", ] [[package]] name = "crossbeam-utils" -version = "0.8.1" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" dependencies = [ - "autocfg 1.0.1", "cfg-if 1.0.0", "lazy_static", ] @@ -2085,7 +2082,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8e24825d3123194a212e3daf8ddac150713cec4f1e126dc3c12ba207f0b5d77" dependencies = [ "chrono", - "crossbeam-channel 0.5.0", + "crossbeam-channel 0.5.1", "glean-core", "inherent", "log", @@ -2437,7 +2434,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" dependencies = [ - "autocfg 1.0.1", + "autocfg", "hashbrown", ] @@ -2667,7 +2664,7 @@ name = "kvstore" version = "0.1.0" dependencies = [ "atomic_refcell", - "crossbeam-utils 0.8.1", + "crossbeam-utils 0.8.5", "cstr", "lazy_static", "libc", @@ -3089,7 +3086,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" dependencies = [ "adler", - "autocfg 1.0.1", + "autocfg", ] [[package]] @@ -3524,7 +3521,7 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ - "autocfg 1.0.1", + "autocfg", "num-integer", "num-traits", ] @@ -3546,7 +3543,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg 1.0.1", + "autocfg", "num-traits", ] @@ -3556,7 +3553,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "autocfg 1.0.1", + "autocfg", ] [[package]] @@ -4149,7 +4146,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf6960dc9a5b4ee8d3e4c5787b4a112a8818e0290a42ff664ad60692fdf2032" dependencies = [ - "autocfg 1.0.1", + "autocfg", "crossbeam-deque", "either", "rayon-core", @@ -4163,7 +4160,7 @@ checksum = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf" dependencies = [ "crossbeam-channel 0.4.4", "crossbeam-deque", - "crossbeam-utils 0.7.0", + "crossbeam-utils 0.7.2", "lazy_static", "num_cpus", ] @@ -4387,7 +4384,7 @@ checksum = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" dependencies = [ "base64 0.10.1", "blake2b_simd", - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.6.6", ] [[package]] @@ -5269,7 +5266,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6df436c42b0c3330a82d855d2ef017cd793090ad550a6bc2184f4b933532ab" dependencies = [ - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.6.6", "futures 0.1.29", ] @@ -5331,7 +5328,7 @@ checksum = "f0c32ffea4827978e9aa392d2f743d973c1dfa3730a2ed3f22ce1e6984da848c" dependencies = [ "crossbeam-deque", "crossbeam-queue", - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.6.6", "futures 0.1.29", "lazy_static", "log", @@ -5346,7 +5343,7 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" dependencies = [ - "crossbeam-utils 0.6.5", + "crossbeam-utils 0.6.6", "futures 0.1.29", "slab", "tokio-executor", @@ -5786,7 +5783,7 @@ dependencies = [ "byteorder", "core-foundation", "core-graphics", - "crossbeam-channel 0.5.0", + "crossbeam-channel 0.5.1", "derive_more", "euclid", "malloc_size_of_derive", @@ -6037,7 +6034,7 @@ dependencies = [ name = "xulstore" version = "0.1.0" dependencies = [ - "crossbeam-utils 0.8.1", + "crossbeam-utils 0.8.5", "cstr", "libc", "log", diff --git a/Cargo.toml b/Cargo.toml index ef1cbabbce6a143d11dde20161b405263f29ac6e..32119df16e3120872b5b47b0c9f7a60d7cf7e28a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,10 +97,6 @@ rev = "824fa69756523f2b6d49029fe25de94130b1f144" [patch.crates-io.autocfg] path = "third_party/rust/autocfg" -[patch.crates-io.autocfg01] -path = "third_party/rust/autocfg-0.1.6" -package = "autocfg" - # Patch mio 0.6 to use winapi 0.3 and miow 0.3, getting rid of winapi 0.2. # There is not going to be new version of mio 0.6, mio now being >= 0.7.11. [patch.crates-io.mio] diff --git a/third_party/rust/autocfg-0.1.6/.cargo-checksum.json b/third_party/rust/autocfg-0.1.6/.cargo-checksum.json deleted file mode 100644 index e7bd53b6e17f805b09b87e925ea4f313da7097de..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.lock":"461e5e87b13d7faf25813b08b5003060c39d8af0953f30d5b80ae0926c888022","Cargo.toml":"1eded5c9954b3bb92bb2c7403e026198e66a2a42199db06fc9cafddc8d1fd677","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"27995d58ad5c1145c1a8cd86244ce844886958a35eb2b78c6b772748669999ac","README.md":"ba9a1621483e0b9f017f07c282d00d5cf3a2d8660cca6df6b14941319d748953","examples/integers.rs":"589ff4271566dfa322becddf3e2c7b592e6e0bc97b02892ce75619b7e452e930","examples/paths.rs":"1b30e466b824ce8df7ad0a55334424131d9d2573d6cf9f7d5d50c09c8901d526","examples/traits.rs":"cbee6a3e1f7db60b02ae25b714926517144a77cb492021f492774cf0e1865a9e","examples/versions.rs":"38535e6d9f5bfae0de474a3db79a40e8f5da8ba9334c5ff4c363de9bc99d4d12","src/error.rs":"12de7dafea4a35d1dc2f0fa79bfa038386bbbea72bf083979f4ddf227999eeda","src/lib.rs":"411d8dbc48ab0f67cb10243f1e16b235407818c96556c838182e4004da995dff","src/tests.rs":"0b1353344e832553d328c47f1639ced877b5dff70fd2024d84130bd1c33eee07","src/version.rs":"175727d5f02f2fe2271ddc9b041db2a5b9c6fe0f95afd17c73a4d982612764a3"},"package":"b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"} \ No newline at end of file diff --git a/third_party/rust/autocfg-0.1.6/Cargo.lock b/third_party/rust/autocfg-0.1.6/Cargo.lock deleted file mode 100644 index 4f899ca2928957bd275d39bb2f86719f4456c9f6..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/Cargo.lock +++ /dev/null @@ -1,6 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "autocfg" -version = "0.1.6" - diff --git a/third_party/rust/autocfg-0.1.6/Cargo.toml b/third_party/rust/autocfg-0.1.6/Cargo.toml deleted file mode 100644 index 4453db3d9817dbdf872fd1ab2ac009208cd78e7f..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies -# -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -name = "autocfg" -version = "0.1.6" -authors = ["Josh Stone <cuviper@gmail.com>"] -description = "Automatic cfg for Rust compiler features" -readme = "README.md" -keywords = ["rustc", "build", "autoconf"] -categories = ["development-tools::build-utils"] -license = "Apache-2.0/MIT" -repository = "https://github.com/cuviper/autocfg" - -[dependencies] diff --git a/third_party/rust/autocfg-0.1.6/README.md b/third_party/rust/autocfg-0.1.6/README.md deleted file mode 100644 index 40004a88e80533f35c9c7650da99e8a84b88ae37..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/README.md +++ /dev/null @@ -1,81 +0,0 @@ -autocfg -======= - -[](https://crates.io/crates/autocfg) -[](https://docs.rs/autocfg) - -[](https://travis-ci.org/cuviper/autocfg) - -A Rust library for build scripts to automatically configure code based on -compiler support. Code snippets are dynamically tested to see if the `rustc` -will accept them, rather than hard-coding specific version support. - - -## Usage - -Add this to your `Cargo.toml`: - -```toml -[build-dependencies] -autocfg = "0.1" -``` - -Then use it in your `build.rs` script to detect compiler features. For -example, to test for 128-bit integer support, it might look like: - -```rust -extern crate autocfg; - -fn main() { - let ac = autocfg::new(); - ac.emit_has_type("i128"); - - // (optional) We don't need to rerun for anything external. - autocfg::rerun_path(file!()); -} -``` - -If the type test succeeds, this will write a `cargo:rustc-cfg=has_i128` line -for Cargo, which translates to Rust arguments `--cfg has_i128`. Then in the -rest of your Rust code, you can add `#[cfg(has_i128)]` conditions on code that -should only be used when the compiler supports it. - - -## Release Notes - -- 0.1.6 (2019-08-19) - - Add `probe`/`emit_sysroot_crate`, by @leo60228 - -- 0.1.5 (2019-07-16) - - Mask some warnings from newer rustc. - -- 0.1.4 (2019-05-22) - - Relax `std`/`no_std` probing to a warning instead of an error. - - Improve `rustc` bootstrap compatibility. - -- 0.1.3 (2019-05-21) - - Auto-detects if `#![no_std]` is needed for the `$TARGET` - -- 0.1.2 (2019-01-16) - - Add `rerun_env(ENV)` to print `cargo:rerun-if-env-changed=ENV` - - Add `rerun_path(PATH)` to print `cargo:rerun-if-changed=PATH` - - -## Minimum Rust version policy - -This crate's minimum supported `rustc` version is `1.0.0`. Compatibility is -its entire reason for existence, so this crate will be extremely conservative -about raising this requirement. If this is ever deemed necessary, it will be -treated as a major breaking change for semver purposes. - - -## License - -This project is licensed under either of - - * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or - http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or - http://opensource.org/licenses/MIT) - -at your option. diff --git a/third_party/rust/autocfg-0.1.6/examples/integers.rs b/third_party/rust/autocfg-0.1.6/examples/integers.rs deleted file mode 100644 index 23d4cba6ee3e96e8ee90d701d035478a73841ecc..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/examples/integers.rs +++ /dev/null @@ -1,9 +0,0 @@ -extern crate autocfg; - -fn main() { - // Normally, cargo will set `OUT_DIR` for build scripts. - let ac = autocfg::AutoCfg::with_dir("target").unwrap(); - for i in 3..8 { - ac.emit_has_type(&format!("i{}", 1 << i)); - } -} diff --git a/third_party/rust/autocfg-0.1.6/examples/paths.rs b/third_party/rust/autocfg-0.1.6/examples/paths.rs deleted file mode 100644 index b7a6ca7a25f7b35ae2e535ccc16cc1a53339f90f..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/examples/paths.rs +++ /dev/null @@ -1,22 +0,0 @@ -extern crate autocfg; - -fn main() { - // Normally, cargo will set `OUT_DIR` for build scripts. - let ac = autocfg::AutoCfg::with_dir("target").unwrap(); - - // since ancient times... - ac.emit_has_path("std::vec::Vec"); - ac.emit_path_cfg("std::vec::Vec", "has_vec"); - - // rustc 1.10.0 - ac.emit_has_path("std::panic::PanicInfo"); - ac.emit_path_cfg("std::panic::PanicInfo", "has_panic_info"); - - // rustc 1.20.0 - ac.emit_has_path("std::mem::ManuallyDrop"); - ac.emit_path_cfg("std::mem::ManuallyDrop", "has_manually_drop"); - - // rustc 1.25.0 - ac.emit_has_path("std::ptr::NonNull"); - ac.emit_path_cfg("std::ptr::NonNull", "has_non_null"); -} diff --git a/third_party/rust/autocfg-0.1.6/examples/traits.rs b/third_party/rust/autocfg-0.1.6/examples/traits.rs deleted file mode 100644 index c1ca00385cd403b9fa0bcca1f8c746d419ed22ce..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/examples/traits.rs +++ /dev/null @@ -1,26 +0,0 @@ -extern crate autocfg; - -fn main() { - // Normally, cargo will set `OUT_DIR` for build scripts. - let ac = autocfg::AutoCfg::with_dir("target").unwrap(); - - // since ancient times... - ac.emit_has_trait("std::ops::Add"); - ac.emit_trait_cfg("std::ops::Add", "has_ops"); - - // trait parameters have to be provided - ac.emit_has_trait("std::borrow::Borrow<str>"); - ac.emit_trait_cfg("std::borrow::Borrow<str>", "has_borrow"); - - // rustc 1.8.0 - ac.emit_has_trait("std::ops::AddAssign"); - ac.emit_trait_cfg("std::ops::AddAssign", "has_assign_ops"); - - // rustc 1.12.0 - ac.emit_has_trait("std::iter::Sum"); - ac.emit_trait_cfg("std::iter::Sum", "has_sum"); - - // rustc 1.28.0 - ac.emit_has_trait("std::alloc::GlobalAlloc"); - ac.emit_trait_cfg("std::alloc::GlobalAlloc", "has_global_alloc"); -} diff --git a/third_party/rust/autocfg-0.1.6/examples/versions.rs b/third_party/rust/autocfg-0.1.6/examples/versions.rs deleted file mode 100644 index 992919b7c642806e52ae35db49a9b3e3dd787ace..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/examples/versions.rs +++ /dev/null @@ -1,9 +0,0 @@ -extern crate autocfg; - -fn main() { - // Normally, cargo will set `OUT_DIR` for build scripts. - let ac = autocfg::AutoCfg::with_dir("target").unwrap(); - for i in 0..100 { - ac.emit_rustc_version(1, i); - } -} diff --git a/third_party/rust/autocfg-0.1.6/src/error.rs b/third_party/rust/autocfg-0.1.6/src/error.rs deleted file mode 100644 index 4624835451b05ce906f295546fb198481042abd9..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/src/error.rs +++ /dev/null @@ -1,69 +0,0 @@ -use std::error; -use std::fmt; -use std::io; -use std::num; -use std::str; - -/// A common error type for the `autocfg` crate. -#[derive(Debug)] -pub struct Error { - kind: ErrorKind, -} - -impl error::Error for Error { - fn description(&self) -> &str { - "AutoCfg error" - } - - fn cause(&self) -> Option<&error::Error> { - match self.kind { - ErrorKind::Io(ref e) => Some(e), - ErrorKind::Num(ref e) => Some(e), - ErrorKind::Utf8(ref e) => Some(e), - ErrorKind::Other(_) => None, - } - } -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match self.kind { - ErrorKind::Io(ref e) => e.fmt(f), - ErrorKind::Num(ref e) => e.fmt(f), - ErrorKind::Utf8(ref e) => e.fmt(f), - ErrorKind::Other(s) => s.fmt(f), - } - } -} - -#[derive(Debug)] -enum ErrorKind { - Io(io::Error), - Num(num::ParseIntError), - Utf8(str::Utf8Error), - Other(&'static str), -} - -pub fn from_io(e: io::Error) -> Error { - Error { - kind: ErrorKind::Io(e), - } -} - -pub fn from_num(e: num::ParseIntError) -> Error { - Error { - kind: ErrorKind::Num(e), - } -} - -pub fn from_utf8(e: str::Utf8Error) -> Error { - Error { - kind: ErrorKind::Utf8(e), - } -} - -pub fn from_str(s: &'static str) -> Error { - Error { - kind: ErrorKind::Other(s), - } -} diff --git a/third_party/rust/autocfg-0.1.6/src/lib.rs b/third_party/rust/autocfg-0.1.6/src/lib.rs deleted file mode 100644 index ea4ed03ca72016408741ccace64dbdf2ab22f85b..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/src/lib.rs +++ /dev/null @@ -1,329 +0,0 @@ -//! A Rust library for build scripts to automatically configure code based on -//! compiler support. Code snippets are dynamically tested to see if the `rustc` -//! will accept them, rather than hard-coding specific version support. -//! -//! -//! ## Usage -//! -//! Add this to your `Cargo.toml`: -//! -//! ```toml -//! [build-dependencies] -//! autocfg = "0.1" -//! ``` -//! -//! Then use it in your `build.rs` script to detect compiler features. For -//! example, to test for 128-bit integer support, it might look like: -//! -//! ```rust -//! extern crate autocfg; -//! -//! fn main() { -//! # // Normally, cargo will set `OUT_DIR` for build scripts. -//! # std::env::set_var("OUT_DIR", "target"); -//! let ac = autocfg::new(); -//! ac.emit_has_type("i128"); -//! -//! // (optional) We don't need to rerun for anything external. -//! autocfg::rerun_path(file!()); -//! } -//! ``` -//! -//! If the type test succeeds, this will write a `cargo:rustc-cfg=has_i128` line -//! for Cargo, which translates to Rust arguments `--cfg has_i128`. Then in the -//! rest of your Rust code, you can add `#[cfg(has_i128)]` conditions on code that -//! should only be used when the compiler supports it. - -#![deny(missing_debug_implementations)] -#![deny(missing_docs)] -// allow future warnings that can't be fixed while keeping 1.0 compatibility -#![allow(unknown_lints)] -#![allow(bare_trait_objects)] -#![allow(ellipsis_inclusive_range_patterns)] -#![allow(warnings)] - -use std::env; -use std::ffi::OsString; -use std::fs; -use std::io::{stderr, Write}; -use std::path::PathBuf; -use std::process::{Command, Stdio}; -#[allow(deprecated)] -use std::sync::atomic::ATOMIC_USIZE_INIT; -use std::sync::atomic::{AtomicUsize, Ordering}; - -mod error; -pub use error::Error; - -mod version; -use version::Version; - -#[cfg(test)] -mod tests; - -/// Helper to detect compiler features for `cfg` output in build scripts. -#[derive(Clone, Debug)] -pub struct AutoCfg { - out_dir: PathBuf, - rustc: PathBuf, - rustc_version: Version, - target: Option<OsString>, - no_std: bool, -} - -/// Writes a config flag for rustc on standard out. -/// -/// This looks like: `cargo:rustc-cfg=CFG` -/// -/// Cargo will use this in arguments to rustc, like `--cfg CFG`. -pub fn emit(cfg: &str) { - println!("cargo:rustc-cfg={}", cfg); -} - -/// Writes a line telling Cargo to rerun the build script if `path` changes. -/// -/// This looks like: `cargo:rerun-if-changed=PATH` -/// -/// This requires at least cargo 0.7.0, corresponding to rustc 1.6.0. Earlier -/// versions of cargo will simply ignore the directive. -pub fn rerun_path(path: &str) { - println!("cargo:rerun-if-changed={}", path); -} - -/// Writes a line telling Cargo to rerun the build script if the environment -/// variable `var` changes. -/// -/// This looks like: `cargo:rerun-if-env-changed=VAR` -/// -/// This requires at least cargo 0.21.0, corresponding to rustc 1.20.0. Earlier -/// versions of cargo will simply ignore the directive. -pub fn rerun_env(var: &str) { - println!("cargo:rerun-if-env-changed={}", var); -} - -/// Create a new `AutoCfg` instance. -/// -/// # Panics -/// -/// Panics if `AutoCfg::new()` returns an error. -pub fn new() -> AutoCfg { - AutoCfg::new().unwrap() -} - -impl AutoCfg { - /// Create a new `AutoCfg` instance. - /// - /// # Common errors - /// - /// - `rustc` can't be executed, from `RUSTC` or in the `PATH`. - /// - The version output from `rustc` can't be parsed. - /// - `OUT_DIR` is not set in the environment, or is not a writable directory. - /// - pub fn new() -> Result<Self, Error> { - match env::var_os("OUT_DIR") { - Some(d) => Self::with_dir(d), - None => Err(error::from_str("no OUT_DIR specified!")), - } - } - - /// Create a new `AutoCfg` instance with the specified output directory. - /// - /// # Common errors - /// - /// - `rustc` can't be executed, from `RUSTC` or in the `PATH`. - /// - The version output from `rustc` can't be parsed. - /// - `dir` is not a writable directory. - /// - pub fn with_dir<T: Into<PathBuf>>(dir: T) -> Result<Self, Error> { - let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into()); - let rustc: PathBuf = rustc.into(); - let rustc_version = try!(Version::from_rustc(&rustc)); - - // Sanity check the output directory - let dir = dir.into(); - let meta = try!(fs::metadata(&dir).map_err(error::from_io)); - if !meta.is_dir() || meta.permissions().readonly() { - return Err(error::from_str("output path is not a writable directory")); - } - - let mut ac = AutoCfg { - out_dir: dir, - rustc: rustc, - rustc_version: rustc_version, - target: env::var_os("TARGET"), - no_std: false, - }; - - // Sanity check with and without `std`. - if !ac.probe("").unwrap_or(false) { - ac.no_std = true; - if !ac.probe("").unwrap_or(false) { - // Neither worked, so assume nothing... - ac.no_std = false; - let warning = b"warning: autocfg could not probe for `std`\n"; - stderr().write_all(warning).ok(); - } - } - Ok(ac) - } - - /// Test whether the current `rustc` reports a version greater than - /// or equal to "`major`.`minor`". - pub fn probe_rustc_version(&self, major: usize, minor: usize) -> bool { - self.rustc_version >= Version::new(major, minor, 0) - } - - /// Sets a `cfg` value of the form `rustc_major_minor`, like `rustc_1_29`, - /// if the current `rustc` is at least that version. - pub fn emit_rustc_version(&self, major: usize, minor: usize) { - if self.probe_rustc_version(major, minor) { - emit(&format!("rustc_{}_{}", major, minor)); - } - } - - fn probe<T: AsRef<[u8]>>(&self, code: T) -> Result<bool, Error> { - #[allow(deprecated)] - static ID: AtomicUsize = ATOMIC_USIZE_INIT; - - let id = ID.fetch_add(1, Ordering::Relaxed); - let mut command = Command::new(&self.rustc); - command - .arg("--crate-name") - .arg(format!("probe{}", id)) - .arg("--crate-type=lib") - .arg("--out-dir") - .arg(&self.out_dir) - .arg("--emit=llvm-ir"); - - if let Some(target) = self.target.as_ref() { - command.arg("--target").arg(target); - } - - command.arg("-").stdin(Stdio::piped()).stderr(Stdio::null()); - let mut child = try!(command.spawn().map_err(error::from_io)); - let mut stdin = child.stdin.take().expect("rustc stdin"); - - if self.no_std { - try!(stdin.write_all(b"#![no_std]\n").map_err(error::from_io)); - } - try!(stdin.write_all(code.as_ref()).map_err(error::from_io)); - drop(stdin); - - let status = try!(child.wait().map_err(error::from_io)); - Ok(status.success()) - } - - /// Tests whether the given sysroot crate can be used. - /// - /// The test code is subject to change, but currently looks like: - /// - /// ```ignore - /// extern crate CRATE as probe; - /// ``` - pub fn probe_sysroot_crate(&self, name: &str) -> bool { - self.probe(format!("extern crate {} as probe;", name)) // `as _` wasn't stabilized until Rust 1.33 - .unwrap_or(false) - } - - /// Emits a config value `has_CRATE` if `probe_sysroot_crate` returns true. - pub fn emit_sysroot_crate(&self, name: &str) { - if self.probe_sysroot_crate(name) { - emit(&format!("has_{}", mangle(name))); - } - } - - /// Tests whether the given path can be used. - /// - /// The test code is subject to change, but currently looks like: - /// - /// ```ignore - /// pub use PATH; - /// ``` - pub fn probe_path(&self, path: &str) -> bool { - self.probe(format!("pub use {};", path)).unwrap_or(false) - } - - /// Emits a config value `has_PATH` if `probe_path` returns true. - /// - /// Any non-identifier characters in the `path` will be replaced with - /// `_` in the generated config value. - pub fn emit_has_path(&self, path: &str) { - if self.probe_path(path) { - emit(&format!("has_{}", mangle(path))); - } - } - - /// Emits the given `cfg` value if `probe_path` returns true. - pub fn emit_path_cfg(&self, path: &str, cfg: &str) { - if self.probe_path(path) { - emit(cfg); - } - } - - /// Tests whether the given trait can be used. - /// - /// The test code is subject to change, but currently looks like: - /// - /// ```ignore - /// pub trait Probe: TRAIT + Sized {} - /// ``` - pub fn probe_trait(&self, name: &str) -> bool { - self.probe(format!("pub trait Probe: {} + Sized {{}}", name)) - .unwrap_or(false) - } - - /// Emits a config value `has_TRAIT` if `probe_trait` returns true. - /// - /// Any non-identifier characters in the trait `name` will be replaced with - /// `_` in the generated config value. - pub fn emit_has_trait(&self, name: &str) { - if self.probe_trait(name) { - emit(&format!("has_{}", mangle(name))); - } - } - - /// Emits the given `cfg` value if `probe_trait` returns true. - pub fn emit_trait_cfg(&self, name: &str, cfg: &str) { - if self.probe_trait(name) { - emit(cfg); - } - } - - /// Tests whether the given type can be used. - /// - /// The test code is subject to change, but currently looks like: - /// - /// ```ignore - /// pub type Probe = TYPE; - /// ``` - pub fn probe_type(&self, name: &str) -> bool { - self.probe(format!("pub type Probe = {};", name)) - .unwrap_or(false) - } - - /// Emits a config value `has_TYPE` if `probe_type` returns true. - /// - /// Any non-identifier characters in the type `name` will be replaced with - /// `_` in the generated config value. - pub fn emit_has_type(&self, name: &str) { - if self.probe_type(name) { - emit(&format!("has_{}", mangle(name))); - } - } - - /// Emits the given `cfg` value if `probe_type` returns true. - pub fn emit_type_cfg(&self, name: &str, cfg: &str) { - if self.probe_type(name) { - emit(cfg); - } - } -} - -fn mangle(s: &str) -> String { - s.chars() - .map(|c| match c { - 'A'...'Z' | 'a'...'z' | '0'...'9' => c, - _ => '_', - }) - .collect() -} diff --git a/third_party/rust/autocfg-0.1.6/src/tests.rs b/third_party/rust/autocfg-0.1.6/src/tests.rs deleted file mode 100644 index 304d989bcb408221b1b074acc6a7edd2f3e2a2ef..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/src/tests.rs +++ /dev/null @@ -1,99 +0,0 @@ -use super::AutoCfg; - -impl AutoCfg { - fn core_std(&self, path: &str) -> String { - let krate = if self.no_std { "core" } else { "std" }; - format!("{}::{}", krate, path) - } -} - -#[test] -fn autocfg_version() { - let ac = AutoCfg::with_dir("target").unwrap(); - println!("version: {:?}", ac.rustc_version); - assert!(ac.probe_rustc_version(1, 0)); -} - -#[test] -fn version_cmp() { - use super::version::Version; - let v123 = Version::new(1, 2, 3); - - assert!(Version::new(1, 0, 0) < v123); - assert!(Version::new(1, 2, 2) < v123); - assert!(Version::new(1, 2, 3) == v123); - assert!(Version::new(1, 2, 4) > v123); - assert!(Version::new(1, 10, 0) > v123); - assert!(Version::new(2, 0, 0) > v123); -} - -#[test] -fn probe_add() { - let ac = AutoCfg::with_dir("target").unwrap(); - let add = ac.core_std("ops::Add"); - let add_rhs = ac.core_std("ops::Add<i32>"); - let add_rhs_output = ac.core_std("ops::Add<i32, Output = i32>"); - assert!(ac.probe_path(&add)); - assert!(ac.probe_trait(&add)); - assert!(ac.probe_trait(&add_rhs)); - assert!(ac.probe_trait(&add_rhs_output)); - assert!(ac.probe_type(&add_rhs_output)); -} - -#[test] -fn probe_as_ref() { - let ac = AutoCfg::with_dir("target").unwrap(); - let as_ref = ac.core_std("convert::AsRef"); - let as_ref_str = ac.core_std("convert::AsRef<str>"); - assert!(ac.probe_path(&as_ref)); - assert!(ac.probe_trait(&as_ref_str)); - assert!(ac.probe_type(&as_ref_str)); -} - -#[test] -fn probe_i128() { - let ac = AutoCfg::with_dir("target").unwrap(); - let missing = !ac.probe_rustc_version(1, 26); - let i128_path = ac.core_std("i128"); - assert!(missing ^ ac.probe_path(&i128_path)); - assert!(missing ^ ac.probe_type("i128")); -} - -#[test] -fn probe_sum() { - let ac = AutoCfg::with_dir("target").unwrap(); - let missing = !ac.probe_rustc_version(1, 12); - let sum = ac.core_std("iter::Sum"); - let sum_i32 = ac.core_std("iter::Sum<i32>"); - assert!(missing ^ ac.probe_path(&sum)); - assert!(missing ^ ac.probe_trait(&sum)); - assert!(missing ^ ac.probe_trait(&sum_i32)); - assert!(missing ^ ac.probe_type(&sum_i32)); -} - -#[test] -fn probe_std() { - let ac = AutoCfg::with_dir("target").unwrap(); - assert_eq!(ac.probe_sysroot_crate("std"), !ac.no_std); -} - -#[test] -fn probe_alloc() { - let ac = AutoCfg::with_dir("target").unwrap(); - let missing = !ac.probe_rustc_version(1, 36); - assert!(missing ^ ac.probe_sysroot_crate("alloc")); -} - -#[test] -fn probe_bad_sysroot_crate() { - let ac = AutoCfg::with_dir("target").unwrap(); - assert!(!ac.probe_sysroot_crate("doesnt_exist")); -} - -#[test] -fn probe_no_std() { - let ac = AutoCfg::with_dir("target").unwrap(); - assert!(ac.probe_type("i32")); - assert!(ac.probe_type("[i32]")); - assert_eq!(ac.probe_type("Vec<i32>"), !ac.no_std); -} diff --git a/third_party/rust/autocfg-0.1.6/src/version.rs b/third_party/rust/autocfg-0.1.6/src/version.rs deleted file mode 100644 index 378c21e61e0cdc15253124e63d20503f599b679e..0000000000000000000000000000000000000000 --- a/third_party/rust/autocfg-0.1.6/src/version.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::path::Path; -use std::process::Command; -use std::str; - -use super::{error, Error}; - -/// A version structure for making relative comparisons. -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct Version { - major: usize, - minor: usize, - patch: usize, -} - -impl Version { - /// Creates a `Version` instance for a specific `major.minor.patch` version. - pub fn new(major: usize, minor: usize, patch: usize) -> Self { - Version { - major: major, - minor: minor, - patch: patch, - } - } - - pub fn from_rustc(rustc: &Path) -> Result<Self, Error> { - // Get rustc's verbose version - let output = try!(Command::new(rustc) - .args(&["--version", "--verbose"]) - .output() - .map_err(error::from_io)); - if !output.status.success() { - return Err(error::from_str("could not execute rustc")); - } - let output = try!(str::from_utf8(&output.stdout).map_err(error::from_utf8)); - - // Find the release line in the verbose version output. - let release = match output.lines().find(|line| line.starts_with("release: ")) { - Some(line) => &line["release: ".len()..], - None => return Err(error::from_str("could not find rustc release")), - }; - - // Strip off any extra channel info, e.g. "-beta.N", "-nightly" - let version = match release.find('-') { - Some(i) => &release[..i], - None => release, - }; - - // Split the version into semver components. - let mut iter = version.splitn(3, '.'); - let major = try!(iter.next().ok_or(error::from_str("missing major version"))); - let minor = try!(iter.next().ok_or(error::from_str("missing minor version"))); - let patch = try!(iter.next().ok_or(error::from_str("missing patch version"))); - - Ok(Version::new( - try!(major.parse().map_err(error::from_num)), - try!(minor.parse().map_err(error::from_num)), - try!(patch.parse().map_err(error::from_num)), - )) - } -} diff --git a/third_party/rust/crossbeam-channel/.cargo-checksum.json b/third_party/rust/crossbeam-channel/.cargo-checksum.json index e232bc9cbefe041094f4629b9a55a13a6d033124..11d72285ceff64668d4d3e57c6f35674daa47d1e 100644 --- a/third_party/rust/crossbeam-channel/.cargo-checksum.json +++ b/third_party/rust/crossbeam-channel/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"0d433ba4c2a327604b582aa0cdbe7b841ee9dcca526f6cb368a07c389c485096","Cargo.lock":"97e544df9b9e169d315994dc220e7a274ac039a3a4f372f7cab333a2e93d9b96","Cargo.toml":"a493466e1330e58126818f0e46b82350ad9e6a7811ca6817159fcdd89c8c871a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","LICENSE-THIRD-PARTY":"924a49392dc8304def57586be4ebd69aaf51e16fd245b55b4b69ad2cce6b715a","README.md":"d2c041f6fa5da30a6f87377421a8de4010c0c002dbff777e18ad2f8b36a65378","benches/crossbeam.rs":"f5720508d3458f2451271b9887f7557823304bd38288c928b0d6aa1f459865e5","examples/fibonacci.rs":"6a26ecd74c7493d2c93f4280c0804afc19adc612b77b3d9fea433119ff472a44","examples/matching.rs":"63c250e164607a7a9f643d46f107bb5da846d49e89cf9069909562d20e530f71","examples/stopwatch.rs":"87e4613e24083e877d97aaefdc6c78ee0308c3a2994974b2cbc7df042a82d488","src/channel.rs":"de23e68e7fa16a1e3278bd69f22fd499724e21533b2b601a71dada9cdda97181","src/context.rs":"ad24cabfc50dd5e6ae84aa46a0246da12da1f1a6fa19043244ad25136075c6ca","src/counter.rs":"8b6d4d69db59bc992ddc7ed33f709788c3fab482521bb1adf985f77499506c09","src/err.rs":"fdbde7279a1e74973e5c7d3e835a97836229a357fe465c0ba1a37f2a012d1bef","src/flavors/array.rs":"59d43e7292f5e3f7f1bb7799fdf99d97aae763ac93d2c1c2e0e807cbbae1657b","src/flavors/at.rs":"e6a169d91ee1057080b0ef55f3e38471212b4ef225e2cdc2fd25b2262371f921","src/flavors/list.rs":"fa6667a33e30fad94a8432b78dd70d143e0809ebf80fa881bb6221aca55b4229","src/flavors/mod.rs":"6188db53712b10add58364e3031101833d9fb0e384f3a2894c38c8b11abe4cdf","src/flavors/never.rs":"59ac4a46b5e32780b2b2f338064544a8b4ec1bc8b78a8a9cd0a683bcd01d5d36","src/flavors/tick.rs":"667fcaacb07d7556350a7e59b5906956224c57b1f43b7b0018a5e2dad0d91ff8","src/flavors/zero.rs":"97c13c89bce0ffd4f761a5ecd73e3221bdd320817061ef7bc7d76010da021b77","src/lib.rs":"5873568968cfd92c6970ef9c3b2643a9d68c61f2fe4c724e52243f3b555de758","src/select.rs":"da9446e51bdcc51e878e71d7a97f0b718639ea065d7ddf4fa7b561efebc84a0e","src/select_macro.rs":"96bc9acb9a22588a4e733b0ab0761ad2be9a6b3e03744e8fc9c6de9ae433b696","src/utils.rs":"4ec0d30835f42dffc7614a18c8f005abb40dd33f2b127809b297959c6aa43004","src/waker.rs":"27eb84dcd0eb58f7d0d79d412bb293becc2740f6166d2fc64acb0ad94cfb523e","tests/after.rs":"324c7d773f72bef62d150171f74ba7b7ac1b06f6030b3d4d2b1a35d211956b21","tests/array.rs":"62290dfd66740a1d1017daea8048df09a11ee8ff8eb614a3a0aa5f4d456a7c39","tests/golang.rs":"751743529b0354d152916e0854a0387ca0b3a898a1771c46e1e7fa2b1660edf9","tests/iter.rs":"7563dc7fdf4c63e31dd74ee3fedecdd3aed490f7ef599b98f6f75f929cf79edb","tests/list.rs":"6a9645c00aed88c1ad07d2e416b4f137ccef2e50f389c71589c6ac7d57373e5a","tests/mpsc.rs":"0c4c6b056f5cec77ca19eca45f99b083632700a4b67133e88071a1d22a61d6fe","tests/never.rs":"665441a9fb004f7cd44047619637ebe6766cf2faf58e68e6481397bbfc682e11","tests/ready.rs":"3848ee8bb16cc83269a462d830659ff29f91834eaab0749bca7be02f43d7db51","tests/same_channel.rs":"2bab761443671e841e1b2476bd8082d75533a2f6be7946f5dbcee67cdc82dccb","tests/select.rs":"58aa5421475bd98b3adc02e4241fc77669ca910cf9cac7a8b0a212b2e92cb7c7","tests/select_macro.rs":"00dd7963f79b96abf30851fdab29e86c8424b502a8a7d34abf4bc1714f493ecf","tests/thread_locals.rs":"3611db5502e6af0a8d15187d09fd195381819795544208b946e9f99b04579a81","tests/tick.rs":"06f205ace5fc44daaf1b6900a2e05bb5bda1c6071c1a07524f45769d8855968b","tests/zero.rs":"368eac99c6d9fb679f8dfbe93cdb96b01d77d1b6f840aa4e156b06f1786bb882"},"package":"dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"} \ No newline at end of file +{"files":{"CHANGELOG.md":"74ac49b84461217698d4430f81b1cdcba0595bc4e57216ffc52b8296ac44cd41","Cargo.lock":"7956079bcac40cc40c894f0260266365ecdb1c01c48636ae4c4080977603e7b8","Cargo.toml":"6a7acaffaa30dab2b5ea1f5ab86b20bc97370314ed03472288745b3b969786dc","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","LICENSE-THIRD-PARTY":"b16db96b93b1d7cf7bea533f572091ec6bca3234fbe0a83038be772ff391a44c","README.md":"415a71d4978cfd338a6ae1f1b41284652eccd277a815542c304647dc437a8274","benches/crossbeam.rs":"f5720508d3458f2451271b9887f7557823304bd38288c928b0d6aa1f459865e5","examples/fibonacci.rs":"6a26ecd74c7493d2c93f4280c0804afc19adc612b77b3d9fea433119ff472a44","examples/matching.rs":"63c250e164607a7a9f643d46f107bb5da846d49e89cf9069909562d20e530f71","examples/stopwatch.rs":"f9a00477b41823199e4af06bddeb0c6cfd22e272340eec1b98b333fc59ee6a1f","src/channel.rs":"a9baaad2f414c38cd324a60ac9375ca58462ce6662217683648e9b66cec43a8c","src/context.rs":"ad24cabfc50dd5e6ae84aa46a0246da12da1f1a6fa19043244ad25136075c6ca","src/counter.rs":"c49a9f44587888850edeb62f7c8ecd1acecb39c836834254ff3ac934c478440a","src/err.rs":"fdbde7279a1e74973e5c7d3e835a97836229a357fe465c0ba1a37f2a012d1bef","src/flavors/array.rs":"c125146771265058ac320226456b1e21667e93649531a3d20157f71cd715881d","src/flavors/at.rs":"65bf870b3ddb14738256706b0276f2656ad1fe9cd8eb91737489868edd088e92","src/flavors/list.rs":"50dbe59616c39b5aa184470023ce0cfb1cb0dbd92e1577375d299446981527c0","src/flavors/mod.rs":"3d9d43bc38b0adb18c96c995c2bd3421d8e33ab6c30b20c3c467d21d48e485dc","src/flavors/never.rs":"0e7921922d00c711552fb063c63c78192fa6ddc0762fb81c1713b847495ec39a","src/flavors/tick.rs":"38a479b9f4a72a5ccb9c407a1e7b44d36b6ad0f4e214e39266b12b9564c803dc","src/flavors/zero.rs":"1bda0c5483b04d53f36f9f4a6fe6f87b69f698068771e637e224c09400c6ce83","src/lib.rs":"3a65706d4124844ffc4c8cb1f8cc779631ec94f449f85cbb68364ad3619404f1","src/select.rs":"4eb4b1988c5dffff3e3d2138d14a1b86613bf62b78c45a5c70f65aaee92c11bb","src/select_macro.rs":"96bc9acb9a22588a4e733b0ab0761ad2be9a6b3e03744e8fc9c6de9ae433b696","src/utils.rs":"746fe315d6cfc832e3dda35e5055c0fd5c99907f1303b2ea7eacc4e37c8527e1","src/waker.rs":"9058cc441d467539c439ef88f0be1a187bf122d26fc116ce3e3a0265a693761f","tests/after.rs":"324c7d773f72bef62d150171f74ba7b7ac1b06f6030b3d4d2b1a35d211956b21","tests/array.rs":"574bff53aff0b0a8c365bf3f9ad77bb64675df9e6e0714be9c16eeeeac22e4d5","tests/golang.rs":"ec03806945fecd381cfce0634e2d776741423589c92e1bd4d8a431ac20f5d2d0","tests/iter.rs":"7563dc7fdf4c63e31dd74ee3fedecdd3aed490f7ef599b98f6f75f929cf79edb","tests/list.rs":"cc2971e69fd7f6a94b5463c9d4e9079df7955b37552e16dd66f4c6e65db60d96","tests/mpsc.rs":"0c4c6b056f5cec77ca19eca45f99b083632700a4b67133e88071a1d22a61d6fe","tests/never.rs":"665441a9fb004f7cd44047619637ebe6766cf2faf58e68e6481397bbfc682e11","tests/ready.rs":"eae3d7f16e817e63f3a6ceda062fece3de5e11c7a9631b32b02f23396a9d59c1","tests/same_channel.rs":"2bab761443671e841e1b2476bd8082d75533a2f6be7946f5dbcee67cdc82dccb","tests/select.rs":"3603f450b23f5e0d1e4014a167a9b23ab149b5f418c8b89636f1c02c90501569","tests/select_macro.rs":"00dd7963f79b96abf30851fdab29e86c8424b502a8a7d34abf4bc1714f493ecf","tests/thread_locals.rs":"3611db5502e6af0a8d15187d09fd195381819795544208b946e9f99b04579a81","tests/tick.rs":"dc4a7d3c8dd888ce135fe8a8c67f5dc8b5ab0c3fa57a48459f96d51fa0f1e6d5","tests/zero.rs":"0ff0587cc74569bfe389e0c619217799a960a0dfc5e6354603c88e6eea1b79a1"},"package":"06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"} \ No newline at end of file diff --git a/third_party/rust/crossbeam-channel/CHANGELOG.md b/third_party/rust/crossbeam-channel/CHANGELOG.md index 0a53e8a0b80a9c220993d216c6fb2b468b6ec7be..98fd9f66daaa271ad9bf9d099e10f3131bcc0fa7 100644 --- a/third_party/rust/crossbeam-channel/CHANGELOG.md +++ b/third_party/rust/crossbeam-channel/CHANGELOG.md @@ -1,3 +1,7 @@ +# Version 0.5.1 + +- Fix memory leak in unbounded channel. (#669) + # Version 0.5.0 - Bump the minimum supported Rust version to 1.36. diff --git a/third_party/rust/crossbeam-channel/Cargo.lock b/third_party/rust/crossbeam-channel/Cargo.lock index 91cb58a0f776be0c6b132897695b1d7c0ebe08be..1ae0d57c27dd6a2f35f13adb2e2c298f7d5a3750 100644 --- a/third_party/rust/crossbeam-channel/Cargo.lock +++ b/third_party/rust/crossbeam-channel/Cargo.lock @@ -1,10 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "arc-swap" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034" +version = 3 [[package]] name = "autocfg" @@ -12,29 +8,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "const_fn" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce90df4c658c62f12d78f7508cf92f9173e5184a539c10bfe54a3107b3ffd0f2" - [[package]] name = "crossbeam-channel" -version = "0.5.0" +version = "0.5.1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "crossbeam-utils", "num_cpus", "rand", @@ -43,32 +27,31 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5" +checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" dependencies = [ "autocfg", - "cfg-if 1.0.0", - "const_fn", + "cfg-if", "lazy_static", ] [[package]] name = "getrandom" -version = "0.1.15" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" dependencies = [ - "cfg-if 0.1.10", + "cfg-if", "libc", "wasi", ] [[package]] name = "hermit-abi" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" +checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" dependencies = [ "libc", ] @@ -81,9 +64,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.79" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" +checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" [[package]] name = "num_cpus" @@ -97,17 +80,16 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" [[package]] name = "rand" -version = "0.7.3" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" dependencies = [ - "getrandom", "libc", "rand_chacha", "rand_core", @@ -116,9 +98,9 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" dependencies = [ "ppv-lite86", "rand_core", @@ -126,27 +108,27 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.5.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" dependencies = [ "getrandom", ] [[package]] name = "rand_hc" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" dependencies = [ "rand_core", ] [[package]] name = "signal-hook" -version = "0.1.16" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604508c1418b99dfe1925ca9224829bb2a8a9a04dda655cc01fcad46f4ab05ed" +checksum = "ef33d6d0cd06e0840fba9985aab098c147e67e05cee14d412d3345ed14ff30ac" dependencies = [ "libc", "signal-hook-registry", @@ -154,16 +136,15 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035" +checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" dependencies = [ - "arc-swap", "libc", ] [[package]] name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" diff --git a/third_party/rust/crossbeam-channel/Cargo.toml b/third_party/rust/crossbeam-channel/Cargo.toml index a5c9964af3663ce4c4a82137d7d7a885fcd5e508..abcc485aec3175ee4e30339a349352deb7bf86ff 100644 --- a/third_party/rust/crossbeam-channel/Cargo.toml +++ b/third_party/rust/crossbeam-channel/Cargo.toml @@ -13,12 +13,11 @@ [package] edition = "2018" name = "crossbeam-channel" -version = "0.5.0" +version = "0.5.1" authors = ["The Crossbeam Project Developers"] description = "Multi-producer multi-consumer channels for message passing" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel" documentation = "https://docs.rs/crossbeam-channel" -readme = "README.md" keywords = ["channel", "mpmc", "select", "golang", "message"] categories = ["algorithms", "concurrency", "data-structures"] license = "MIT OR Apache-2.0" @@ -34,10 +33,10 @@ default-features = false version = "1.13.0" [dev-dependencies.rand] -version = "0.7.3" +version = "0.8" [dev-dependencies.signal-hook] -version = "0.1.15" +version = "0.3" [features] default = ["std"] diff --git a/third_party/rust/crossbeam-channel/LICENSE-THIRD-PARTY b/third_party/rust/crossbeam-channel/LICENSE-THIRD-PARTY index d15e32bc714aecfe86b88330c0ed1ab0a4739cd5..ed4df76f4cef9d233f168ef033908ab0809be143 100644 --- a/third_party/rust/crossbeam-channel/LICENSE-THIRD-PARTY +++ b/third_party/rust/crossbeam-channel/LICENSE-THIRD-PARTY @@ -1,37 +1,5 @@ =============================================================================== -Bounded MPMC queue -http://www.1024cores.net/home/code-license - -Copyright (c) 2010-2011 Dmitry Vyukov. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO -EVENT SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The views and conclusions contained in the software and documentation are those -of the authors and should not be interpreted as representing official policies, -either expressed or implied, of Dmitry Vyukov. - -=============================================================================== - matching.go https://creativecommons.org/licenses/by/3.0/legalcode diff --git a/third_party/rust/crossbeam-channel/README.md b/third_party/rust/crossbeam-channel/README.md index eab623a6a9ab22c9a8116208388cf4f0d0b7835e..f5077c556c831b7ac773877f4ab284b874da3a45 100644 --- a/third_party/rust/crossbeam-channel/README.md +++ b/third_party/rust/crossbeam-channel/README.md @@ -2,7 +2,7 @@ []( https://github.com/crossbeam-rs/crossbeam/actions) -[]( +[]( https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel#license) []( https://crates.io/crates/crossbeam-channel) @@ -10,7 +10,7 @@ https://crates.io/crates/crossbeam-channel) https://docs.rs/crossbeam-channel) []( https://www.rust-lang.org) -[](https://discord.gg/BBYwKq) +[](https://discord.com/invite/JXYwgWZ) This crate provides multi-producer multi-consumer channels for message passing. It is an alternative to [`std::sync::mpsc`] with more features and better performance. @@ -41,7 +41,7 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -crossbeam-channel = "0.4" +crossbeam-channel = "0.5" ``` ## Compatibility @@ -73,10 +73,6 @@ This product includes copies and modifications of software developed by third pa [matching.go](http://www.nada.kth.se/~snilsson/concurrency/src/matching.go) by Stefan Nilsson, licensed under Creative Commons Attribution 3.0 Unported License. -* [src/flavors/array.rs](src/flavors/array.rs) is based on - [Bounded MPMC queue](http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue) - by Dmitry Vyukov, licensed under the Simplified BSD License and the Apache License, Version 2.0. - * [tests/mpsc.rs](tests/mpsc.rs) includes modifications of code from The Rust Programming Language, licensed under the MIT License and the Apache License, Version 2.0. diff --git a/third_party/rust/crossbeam-channel/examples/stopwatch.rs b/third_party/rust/crossbeam-channel/examples/stopwatch.rs index 6a67c9eefc46db83dd822fc6a1c5f7e3b46d47a2..98895c5a3a466073fa73b9c68a537b1933732785 100644 --- a/third_party/rust/crossbeam-channel/examples/stopwatch.rs +++ b/third_party/rust/crossbeam-channel/examples/stopwatch.rs @@ -12,13 +12,13 @@ fn main() { use std::time::{Duration, Instant}; use crossbeam_channel::{bounded, select, tick, Receiver}; + use signal_hook::consts::SIGINT; use signal_hook::iterator::Signals; - use signal_hook::SIGINT; // Creates a channel that gets a message every time `SIGINT` is signalled. fn sigint_notifier() -> io::Result<Receiver<()>> { let (s, r) = bounded(100); - let signals = Signals::new(&[SIGINT])?; + let mut signals = Signals::new(&[SIGINT])?; thread::spawn(move || { for _ in signals.forever() { diff --git a/third_party/rust/crossbeam-channel/src/channel.rs b/third_party/rust/crossbeam-channel/src/channel.rs index ebcd6520189bc8b13ba26724f10279984ae8e2fe..8988235db45e240cf7650d280c475cbb435dac4f 100644 --- a/third_party/rust/crossbeam-channel/src/channel.rs +++ b/third_party/rust/crossbeam-channel/src/channel.rs @@ -257,8 +257,6 @@ pub fn at(when: Instant) -> Receiver<Instant> { /// recv(timeout) -> _ => println!("timed out"), /// } /// ``` -/// -/// [`select!`]: macro.select.html pub fn never<T>() -> Receiver<T> { Receiver { flavor: ReceiverFlavor::Never(flavors::never::Channel::new()), @@ -645,7 +643,7 @@ impl<T> Drop for Sender<T> { unsafe { match &self.flavor { SenderFlavor::Array(chan) => chan.release(|c| c.disconnect()), - SenderFlavor::List(chan) => chan.release(|c| c.disconnect()), + SenderFlavor::List(chan) => chan.release(|c| c.disconnect_senders()), SenderFlavor::Zero(chan) => chan.release(|c| c.disconnect()), } } @@ -1137,7 +1135,7 @@ impl<T> Drop for Receiver<T> { unsafe { match &self.flavor { ReceiverFlavor::Array(chan) => chan.release(|c| c.disconnect()), - ReceiverFlavor::List(chan) => chan.release(|c| c.disconnect()), + ReceiverFlavor::List(chan) => chan.release(|c| c.disconnect_receivers()), ReceiverFlavor::Zero(chan) => chan.release(|c| c.disconnect()), ReceiverFlavor::At(_) => {} ReceiverFlavor::Tick(_) => {} @@ -1485,7 +1483,7 @@ impl<T> SelectHandle for Receiver<T> { } /// Writes a message into the channel. -pub unsafe fn write<T>(s: &Sender<T>, token: &mut Token, msg: T) -> Result<(), T> { +pub(crate) unsafe fn write<T>(s: &Sender<T>, token: &mut Token, msg: T) -> Result<(), T> { match &s.flavor { SenderFlavor::Array(chan) => chan.write(token, msg), SenderFlavor::List(chan) => chan.write(token, msg), @@ -1494,7 +1492,7 @@ pub unsafe fn write<T>(s: &Sender<T>, token: &mut Token, msg: T) -> Result<(), T } /// Reads a message from the channel. -pub unsafe fn read<T>(r: &Receiver<T>, token: &mut Token) -> Result<T, ()> { +pub(crate) unsafe fn read<T>(r: &Receiver<T>, token: &mut Token) -> Result<T, ()> { match &r.flavor { ReceiverFlavor::Array(chan) => chan.read(token), ReceiverFlavor::List(chan) => chan.read(token), diff --git a/third_party/rust/crossbeam-channel/src/counter.rs b/third_party/rust/crossbeam-channel/src/counter.rs index 2eaf06782042465fde984a0215c280f6b8a26cd9..2c27f7c6b2e1a2b807e3f468c12e365325d450c6 100644 --- a/third_party/rust/crossbeam-channel/src/counter.rs +++ b/third_party/rust/crossbeam-channel/src/counter.rs @@ -21,7 +21,7 @@ struct Counter<C> { } /// Wraps a channel into the reference counter. -pub fn new<C>(chan: C) -> (Sender<C>, Receiver<C>) { +pub(crate) fn new<C>(chan: C) -> (Sender<C>, Receiver<C>) { let counter = Box::into_raw(Box::new(Counter { senders: AtomicUsize::new(1), receivers: AtomicUsize::new(1), @@ -34,7 +34,7 @@ pub fn new<C>(chan: C) -> (Sender<C>, Receiver<C>) { } /// The sending side. -pub struct Sender<C> { +pub(crate) struct Sender<C> { counter: *mut Counter<C>, } @@ -45,7 +45,7 @@ impl<C> Sender<C> { } /// Acquires another sender reference. - pub fn acquire(&self) -> Sender<C> { + pub(crate) fn acquire(&self) -> Sender<C> { let count = self.counter().senders.fetch_add(1, Ordering::Relaxed); // Cloning senders and calling `mem::forget` on the clones could potentially overflow the @@ -63,7 +63,7 @@ impl<C> Sender<C> { /// Releases the sender reference. /// /// Function `disconnect` will be called if this is the last sender reference. - pub unsafe fn release<F: FnOnce(&C) -> bool>(&self, disconnect: F) { + pub(crate) unsafe fn release<F: FnOnce(&C) -> bool>(&self, disconnect: F) { if self.counter().senders.fetch_sub(1, Ordering::AcqRel) == 1 { disconnect(&self.counter().chan); @@ -89,7 +89,7 @@ impl<C> PartialEq for Sender<C> { } /// The receiving side. -pub struct Receiver<C> { +pub(crate) struct Receiver<C> { counter: *mut Counter<C>, } @@ -100,7 +100,7 @@ impl<C> Receiver<C> { } /// Acquires another receiver reference. - pub fn acquire(&self) -> Receiver<C> { + pub(crate) fn acquire(&self) -> Receiver<C> { let count = self.counter().receivers.fetch_add(1, Ordering::Relaxed); // Cloning receivers and calling `mem::forget` on the clones could potentially overflow the @@ -118,7 +118,7 @@ impl<C> Receiver<C> { /// Releases the receiver reference. /// /// Function `disconnect` will be called if this is the last receiver reference. - pub unsafe fn release<F: FnOnce(&C) -> bool>(&self, disconnect: F) { + pub(crate) unsafe fn release<F: FnOnce(&C) -> bool>(&self, disconnect: F) { if self.counter().receivers.fetch_sub(1, Ordering::AcqRel) == 1 { disconnect(&self.counter().chan); diff --git a/third_party/rust/crossbeam-channel/src/flavors/array.rs b/third_party/rust/crossbeam-channel/src/flavors/array.rs index 323a200c25dc5082c97d11c5148d4716aa18e5bb..c49eef1f04310a5d5b43739118f5a63db22e8d4d 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/array.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/array.rs @@ -5,13 +5,8 @@ //! The implementation is based on Dmitry Vyukov's bounded MPMC queue. //! //! Source: -//! - http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue -//! - https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub -//! -//! Copyright & License: -//! - Copyright (c) 2010-2011 Dmitry Vyukov -//! - Simplified BSD License and Apache License, Version 2.0 -//! - http://www.1024cores.net/home/code-license +//! - <http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue> +//! - <https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub> use std::cell::UnsafeCell; use std::marker::PhantomData; @@ -57,7 +52,7 @@ impl Default for ArrayToken { } /// Bounded channel based on a preallocated array. -pub struct Channel<T> { +pub(crate) struct Channel<T> { /// The head of the channel. /// /// This value is a "stamp" consisting of an index into the buffer, a mark bit, and a lap, but @@ -100,7 +95,7 @@ pub struct Channel<T> { impl<T> Channel<T> { /// Creates a bounded channel of capacity `cap`. - pub fn with_capacity(cap: usize) -> Self { + pub(crate) fn with_capacity(cap: usize) -> Self { assert!(cap > 0, "capacity must be positive"); // Compute constants `mark_bit` and `one_lap`. @@ -143,12 +138,12 @@ impl<T> Channel<T> { } /// Returns a receiver handle to the channel. - pub fn receiver(&self) -> Receiver<'_, T> { + pub(crate) fn receiver(&self) -> Receiver<'_, T> { Receiver(self) } /// Returns a sender handle to the channel. - pub fn sender(&self) -> Sender<'_, T> { + pub(crate) fn sender(&self) -> Sender<'_, T> { Sender(self) } @@ -224,7 +219,7 @@ impl<T> Channel<T> { } /// Writes a message into the channel. - pub unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { + pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { // If there is no slot, the channel is disconnected. if token.array.slot.is_null() { return Err(msg); @@ -314,7 +309,7 @@ impl<T> Channel<T> { } /// Reads a message from the channel. - pub unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { + pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { if token.array.slot.is_null() { // The channel is disconnected. return Err(()); @@ -332,7 +327,7 @@ impl<T> Channel<T> { } /// Attempts to send a message into the channel. - pub fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { + pub(crate) fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { let token = &mut Token::default(); if self.start_send(token) { unsafe { self.write(token, msg).map_err(TrySendError::Disconnected) } @@ -342,7 +337,11 @@ impl<T> Channel<T> { } /// Sends a message into the channel. - pub fn send(&self, msg: T, deadline: Option<Instant>) -> Result<(), SendTimeoutError<T>> { + pub(crate) fn send( + &self, + msg: T, + deadline: Option<Instant>, + ) -> Result<(), SendTimeoutError<T>> { let token = &mut Token::default(); loop { // Try sending a message several times. @@ -391,7 +390,7 @@ impl<T> Channel<T> { } /// Attempts to receive a message without blocking. - pub fn try_recv(&self) -> Result<T, TryRecvError> { + pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { let token = &mut Token::default(); if self.start_recv(token) { @@ -402,7 +401,7 @@ impl<T> Channel<T> { } /// Receives a message from the channel. - pub fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { + pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { let token = &mut Token::default(); loop { // Try receiving a message several times. @@ -453,7 +452,7 @@ impl<T> Channel<T> { } /// Returns the current number of messages inside the channel. - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { loop { // Load the tail, then load the head. let tail = self.tail.load(Ordering::SeqCst); @@ -478,14 +477,15 @@ impl<T> Channel<T> { } /// Returns the capacity of the channel. - pub fn capacity(&self) -> Option<usize> { + #[allow(clippy::unnecessary_wraps)] // This is intentional. + pub(crate) fn capacity(&self) -> Option<usize> { Some(self.cap) } /// Disconnects the channel and wakes up all blocked senders and receivers. /// /// Returns `true` if this call disconnected the channel. - pub fn disconnect(&self) -> bool { + pub(crate) fn disconnect(&self) -> bool { let tail = self.tail.fetch_or(self.mark_bit, Ordering::SeqCst); if tail & self.mark_bit == 0 { @@ -498,12 +498,12 @@ impl<T> Channel<T> { } /// Returns `true` if the channel is disconnected. - pub fn is_disconnected(&self) -> bool { + pub(crate) fn is_disconnected(&self) -> bool { self.tail.load(Ordering::SeqCst) & self.mark_bit != 0 } /// Returns `true` if the channel is empty. - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { let head = self.head.load(Ordering::SeqCst); let tail = self.tail.load(Ordering::SeqCst); @@ -515,7 +515,7 @@ impl<T> Channel<T> { } /// Returns `true` if the channel is full. - pub fn is_full(&self) -> bool { + pub(crate) fn is_full(&self) -> bool { let tail = self.tail.load(Ordering::SeqCst); let head = self.head.load(Ordering::SeqCst); @@ -563,10 +563,10 @@ impl<T> Drop for Channel<T> { } /// Receiver handle to a channel. -pub struct Receiver<'a, T>(&'a Channel<T>); +pub(crate) struct Receiver<'a, T>(&'a Channel<T>); /// Sender handle to a channel. -pub struct Sender<'a, T>(&'a Channel<T>); +pub(crate) struct Sender<'a, T>(&'a Channel<T>); impl<T> SelectHandle for Receiver<'_, T> { fn try_select(&self, token: &mut Token) -> bool { diff --git a/third_party/rust/crossbeam-channel/src/flavors/at.rs b/third_party/rust/crossbeam-channel/src/flavors/at.rs index a2b1b578ec228f46131fdce2714063ff3d4c182a..4581edba1247a9675bd7dbc0e00f88f3ac4b2aa8 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/at.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/at.rs @@ -12,10 +12,10 @@ use crate::select::{Operation, SelectHandle, Token}; use crate::utils; /// Result of a receive operation. -pub type AtToken = Option<Instant>; +pub(crate) type AtToken = Option<Instant>; /// Channel that delivers a message at a certain moment in time -pub struct Channel { +pub(crate) struct Channel { /// The instant at which the message will be delivered. delivery_time: Instant, @@ -26,7 +26,7 @@ pub struct Channel { impl Channel { /// Creates a channel that delivers a message at a certain instant in time. #[inline] - pub fn new_deadline(when: Instant) -> Self { + pub(crate) fn new_deadline(when: Instant) -> Self { Channel { delivery_time: when, received: AtomicBool::new(false), @@ -34,13 +34,13 @@ impl Channel { } /// Creates a channel that delivers a message after a certain duration of time. #[inline] - pub fn new_timeout(dur: Duration) -> Self { + pub(crate) fn new_timeout(dur: Duration) -> Self { Self::new_deadline(Instant::now() + dur) } /// Attempts to receive a message without blocking. #[inline] - pub fn try_recv(&self) -> Result<Instant, TryRecvError> { + pub(crate) fn try_recv(&self) -> Result<Instant, TryRecvError> { // We use relaxed ordering because this is just an optional optimistic check. if self.received.load(Ordering::Relaxed) { // The message has already been received. @@ -64,7 +64,7 @@ impl Channel { /// Receives a message from the channel. #[inline] - pub fn recv(&self, deadline: Option<Instant>) -> Result<Instant, RecvTimeoutError> { + pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<Instant, RecvTimeoutError> { // We use relaxed ordering because this is just an optional optimistic check. if self.received.load(Ordering::Relaxed) { // The message has already been received. @@ -103,13 +103,13 @@ impl Channel { /// Reads a message from the channel. #[inline] - pub unsafe fn read(&self, token: &mut Token) -> Result<Instant, ()> { + pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<Instant, ()> { token.at.ok_or(()) } /// Returns `true` if the channel is empty. #[inline] - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { // We use relaxed ordering because this is just an optional optimistic check. if self.received.load(Ordering::Relaxed) { return true; @@ -127,13 +127,13 @@ impl Channel { /// Returns `true` if the channel is full. #[inline] - pub fn is_full(&self) -> bool { + pub(crate) fn is_full(&self) -> bool { !self.is_empty() } /// Returns the number of messages in the channel. #[inline] - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { if self.is_empty() { 0 } else { @@ -142,8 +142,9 @@ impl Channel { } /// Returns the capacity of the channel. + #[allow(clippy::unnecessary_wraps)] // This is intentional. #[inline] - pub fn capacity(&self) -> Option<usize> { + pub(crate) fn capacity(&self) -> Option<usize> { Some(1) } } diff --git a/third_party/rust/crossbeam-channel/src/flavors/list.rs b/third_party/rust/crossbeam-channel/src/flavors/list.rs index 532e8b6ad41c4e38862d2e5aabf9d0b7995b14d3..5056aa431326ae02eadc235e2a2f9aae48d6d353 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/list.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/list.rs @@ -151,7 +151,7 @@ impl Default for ListToken { /// /// Consecutive messages are grouped into blocks in order to put less pressure on the allocator and /// improve cache efficiency. -pub struct Channel<T> { +pub(crate) struct Channel<T> { /// The head of the channel. head: CachePadded<Position<T>>, @@ -167,7 +167,7 @@ pub struct Channel<T> { impl<T> Channel<T> { /// Creates a new unbounded channel. - pub fn new() -> Self { + pub(crate) fn new() -> Self { Channel { head: CachePadded::new(Position { block: AtomicPtr::new(ptr::null_mut()), @@ -183,12 +183,12 @@ impl<T> Channel<T> { } /// Returns a receiver handle to the channel. - pub fn receiver(&self) -> Receiver<'_, T> { + pub(crate) fn receiver(&self) -> Receiver<'_, T> { Receiver(self) } /// Returns a sender handle to the channel. - pub fn sender(&self) -> Sender<'_, T> { + pub(crate) fn sender(&self) -> Sender<'_, T> { Sender(self) } @@ -231,8 +231,8 @@ impl<T> Channel<T> { if self .tail .block - .compare_and_swap(block, new, Ordering::Release) - == block + .compare_exchange(block, new, Ordering::Release, Ordering::Relaxed) + .is_ok() { self.head.block.store(new, Ordering::Release); block = new; @@ -276,7 +276,7 @@ impl<T> Channel<T> { } /// Writes a message into the channel. - pub unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { + pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { // If there is no slot, the channel is disconnected. if token.list.block.is_null() { return Err(msg); @@ -380,7 +380,7 @@ impl<T> Channel<T> { } /// Reads a message from the channel. - pub unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { + pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { if token.list.block.is_null() { // The channel is disconnected. return Err(()); @@ -405,7 +405,7 @@ impl<T> Channel<T> { } /// Attempts to send a message into the channel. - pub fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { + pub(crate) fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { self.send(msg, None).map_err(|err| match err { SendTimeoutError::Disconnected(msg) => TrySendError::Disconnected(msg), SendTimeoutError::Timeout(_) => unreachable!(), @@ -413,7 +413,11 @@ impl<T> Channel<T> { } /// Sends a message into the channel. - pub fn send(&self, msg: T, _deadline: Option<Instant>) -> Result<(), SendTimeoutError<T>> { + pub(crate) fn send( + &self, + msg: T, + _deadline: Option<Instant>, + ) -> Result<(), SendTimeoutError<T>> { let token = &mut Token::default(); assert!(self.start_send(token)); unsafe { @@ -423,7 +427,7 @@ impl<T> Channel<T> { } /// Attempts to receive a message without blocking. - pub fn try_recv(&self) -> Result<T, TryRecvError> { + pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { let token = &mut Token::default(); if self.start_recv(token) { @@ -434,7 +438,7 @@ impl<T> Channel<T> { } /// Receives a message from the channel. - pub fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { + pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { let token = &mut Token::default(); loop { // Try receiving a message several times. @@ -486,7 +490,7 @@ impl<T> Channel<T> { } /// Returns the current number of messages inside the channel. - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { loop { // Load the tail index, then load the head index. let mut tail = self.tail.index.load(Ordering::SeqCst); @@ -522,14 +526,14 @@ impl<T> Channel<T> { } /// Returns the capacity of the channel. - pub fn capacity(&self) -> Option<usize> { + pub(crate) fn capacity(&self) -> Option<usize> { None } - /// Disconnects the channel and wakes up all blocked receivers. + /// Disconnects senders and wakes up all blocked receivers. /// /// Returns `true` if this call disconnected the channel. - pub fn disconnect(&self) -> bool { + pub(crate) fn disconnect_senders(&self) -> bool { let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); if tail & MARK_BIT == 0 { @@ -540,20 +544,90 @@ impl<T> Channel<T> { } } + /// Disconnects receivers. + /// + /// Returns `true` if this call disconnected the channel. + pub(crate) fn disconnect_receivers(&self) -> bool { + let tail = self.tail.index.fetch_or(MARK_BIT, Ordering::SeqCst); + + if tail & MARK_BIT == 0 { + // If receivers are dropped first, discard all messages to free + // memory eagerly. + self.discard_all_messages(); + true + } else { + false + } + } + + /// Discards all messages. + /// + /// This method should only be called when all receivers are dropped. + fn discard_all_messages(&self) { + let backoff = Backoff::new(); + let mut tail = self.tail.index.load(Ordering::Acquire); + loop { + let offset = (tail >> SHIFT) % LAP; + if offset != BLOCK_CAP { + break; + } + + // New updates to tail will be rejected by MARK_BIT and aborted unless it's + // at boundary. We need to wait for the updates take affect otherwise there + // can be memory leaks. + backoff.snooze(); + tail = self.tail.index.load(Ordering::Acquire); + } + + let mut head = self.head.index.load(Ordering::Acquire); + let mut block = self.head.block.load(Ordering::Acquire); + + unsafe { + // Drop all messages between head and tail and deallocate the heap-allocated blocks. + while head >> SHIFT != tail >> SHIFT { + let offset = (head >> SHIFT) % LAP; + + if offset < BLOCK_CAP { + // Drop the message in the slot. + let slot = (*block).slots.get_unchecked(offset); + slot.wait_write(); + let p = &mut *slot.msg.get(); + p.as_mut_ptr().drop_in_place(); + } else { + (*block).wait_next(); + // Deallocate the block and move to the next one. + let next = (*block).next.load(Ordering::Acquire); + drop(Box::from_raw(block)); + block = next; + } + + head = head.wrapping_add(1 << SHIFT); + } + + // Deallocate the last remaining block. + if !block.is_null() { + drop(Box::from_raw(block)); + } + } + head &= !MARK_BIT; + self.head.block.store(ptr::null_mut(), Ordering::Release); + self.head.index.store(head, Ordering::Release); + } + /// Returns `true` if the channel is disconnected. - pub fn is_disconnected(&self) -> bool { + pub(crate) fn is_disconnected(&self) -> bool { self.tail.index.load(Ordering::SeqCst) & MARK_BIT != 0 } /// Returns `true` if the channel is empty. - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { let head = self.head.index.load(Ordering::SeqCst); let tail = self.tail.index.load(Ordering::SeqCst); head >> SHIFT == tail >> SHIFT } /// Returns `true` if the channel is full. - pub fn is_full(&self) -> bool { + pub(crate) fn is_full(&self) -> bool { false } } @@ -597,10 +671,10 @@ impl<T> Drop for Channel<T> { } /// Receiver handle to a channel. -pub struct Receiver<'a, T>(&'a Channel<T>); +pub(crate) struct Receiver<'a, T>(&'a Channel<T>); /// Sender handle to a channel. -pub struct Sender<'a, T>(&'a Channel<T>); +pub(crate) struct Sender<'a, T>(&'a Channel<T>); impl<T> SelectHandle for Receiver<'_, T> { fn try_select(&self, token: &mut Token) -> bool { diff --git a/third_party/rust/crossbeam-channel/src/flavors/mod.rs b/third_party/rust/crossbeam-channel/src/flavors/mod.rs index 299e78f69687a8b508ed699157dbeb5b96e6859f..0314bf42097e8643c2b59d2c8efad593a9f008d2 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/mod.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/mod.rs @@ -9,9 +9,9 @@ //! 5. `tick` - Channel that delivers messages periodically. //! 6. `zero` - Zero-capacity channel. -pub mod array; -pub mod at; -pub mod list; -pub mod never; -pub mod tick; -pub mod zero; +pub(crate) mod array; +pub(crate) mod at; +pub(crate) mod list; +pub(crate) mod never; +pub(crate) mod tick; +pub(crate) mod zero; diff --git a/third_party/rust/crossbeam-channel/src/flavors/never.rs b/third_party/rust/crossbeam-channel/src/flavors/never.rs index e49d2147c44b75d97adc64cd8cfce085db159e75..1951e963faf8af1525f1896d546b7b37939f2cd1 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/never.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/never.rs @@ -11,17 +11,17 @@ use crate::select::{Operation, SelectHandle, Token}; use crate::utils; /// This flavor doesn't need a token. -pub type NeverToken = (); +pub(crate) type NeverToken = (); /// Channel that never delivers messages. -pub struct Channel<T> { +pub(crate) struct Channel<T> { _marker: PhantomData<T>, } impl<T> Channel<T> { /// Creates a channel that never delivers messages. #[inline] - pub fn new() -> Self { + pub(crate) fn new() -> Self { Channel { _marker: PhantomData, } @@ -29,44 +29,45 @@ impl<T> Channel<T> { /// Attempts to receive a message without blocking. #[inline] - pub fn try_recv(&self) -> Result<T, TryRecvError> { + pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { Err(TryRecvError::Empty) } /// Receives a message from the channel. #[inline] - pub fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { + pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { utils::sleep_until(deadline); Err(RecvTimeoutError::Timeout) } /// Reads a message from the channel. #[inline] - pub unsafe fn read(&self, _token: &mut Token) -> Result<T, ()> { + pub(crate) unsafe fn read(&self, _token: &mut Token) -> Result<T, ()> { Err(()) } /// Returns `true` if the channel is empty. #[inline] - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { true } /// Returns `true` if the channel is full. #[inline] - pub fn is_full(&self) -> bool { + pub(crate) fn is_full(&self) -> bool { true } /// Returns the number of messages in the channel. #[inline] - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { 0 } /// Returns the capacity of the channel. + #[allow(clippy::unnecessary_wraps)] // This is intentional. #[inline] - pub fn capacity(&self) -> Option<usize> { + pub(crate) fn capacity(&self) -> Option<usize> { Some(0) } } diff --git a/third_party/rust/crossbeam-channel/src/flavors/tick.rs b/third_party/rust/crossbeam-channel/src/flavors/tick.rs index e8e7020ca8e2e2368fca8a8b39e3cb203b136385..d4b1f6c78d49fa37d30260e4f807313c8d28a9f4 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/tick.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/tick.rs @@ -12,10 +12,10 @@ use crate::err::{RecvTimeoutError, TryRecvError}; use crate::select::{Operation, SelectHandle, Token}; /// Result of a receive operation. -pub type TickToken = Option<Instant>; +pub(crate) type TickToken = Option<Instant>; /// Channel that delivers messages periodically. -pub struct Channel { +pub(crate) struct Channel { /// The instant at which the next message will be delivered. delivery_time: AtomicCell<Instant>, @@ -26,7 +26,7 @@ pub struct Channel { impl Channel { /// Creates a channel that delivers messages periodically. #[inline] - pub fn new(dur: Duration) -> Self { + pub(crate) fn new(dur: Duration) -> Self { Channel { delivery_time: AtomicCell::new(Instant::now() + dur), duration: dur, @@ -35,7 +35,7 @@ impl Channel { /// Attempts to receive a message without blocking. #[inline] - pub fn try_recv(&self) -> Result<Instant, TryRecvError> { + pub(crate) fn try_recv(&self) -> Result<Instant, TryRecvError> { loop { let now = Instant::now(); let delivery_time = self.delivery_time.load(); @@ -56,7 +56,7 @@ impl Channel { /// Receives a message from the channel. #[inline] - pub fn recv(&self, deadline: Option<Instant>) -> Result<Instant, RecvTimeoutError> { + pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<Instant, RecvTimeoutError> { loop { let delivery_time = self.delivery_time.load(); let now = Instant::now(); @@ -85,25 +85,25 @@ impl Channel { /// Reads a message from the channel. #[inline] - pub unsafe fn read(&self, token: &mut Token) -> Result<Instant, ()> { + pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<Instant, ()> { token.tick.ok_or(()) } /// Returns `true` if the channel is empty. #[inline] - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { Instant::now() < self.delivery_time.load() } /// Returns `true` if the channel is full. #[inline] - pub fn is_full(&self) -> bool { + pub(crate) fn is_full(&self) -> bool { !self.is_empty() } /// Returns the number of messages in the channel. #[inline] - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { if self.is_empty() { 0 } else { @@ -112,8 +112,9 @@ impl Channel { } /// Returns the capacity of the channel. + #[allow(clippy::unnecessary_wraps)] // This is intentional. #[inline] - pub fn capacity(&self) -> Option<usize> { + pub(crate) fn capacity(&self) -> Option<usize> { Some(1) } } diff --git a/third_party/rust/crossbeam-channel/src/flavors/zero.rs b/third_party/rust/crossbeam-channel/src/flavors/zero.rs index be647b55c82f2282321fcde38f002643954d6417..9790b77c230342045eb536a9fc09f6eae54de142 100644 --- a/third_party/rust/crossbeam-channel/src/flavors/zero.rs +++ b/third_party/rust/crossbeam-channel/src/flavors/zero.rs @@ -16,7 +16,7 @@ use crate::utils::Spinlock; use crate::waker::Waker; /// A pointer to a packet. -pub type ZeroToken = usize; +pub(crate) type ZeroToken = usize; /// A slot for passing one message from a sender to a receiver. struct Packet<T> { @@ -80,7 +80,7 @@ struct Inner { } /// Zero-capacity channel. -pub struct Channel<T> { +pub(crate) struct Channel<T> { /// Inner representation of the channel. inner: Spinlock<Inner>, @@ -90,7 +90,7 @@ pub struct Channel<T> { impl<T> Channel<T> { /// Constructs a new zero-capacity channel. - pub fn new() -> Self { + pub(crate) fn new() -> Self { Channel { inner: Spinlock::new(Inner { senders: Waker::new(), @@ -102,12 +102,12 @@ impl<T> Channel<T> { } /// Returns a receiver handle to the channel. - pub fn receiver(&self) -> Receiver<'_, T> { + pub(crate) fn receiver(&self) -> Receiver<'_, T> { Receiver(self) } /// Returns a sender handle to the channel. - pub fn sender(&self) -> Sender<'_, T> { + pub(crate) fn sender(&self) -> Sender<'_, T> { Sender(self) } @@ -128,7 +128,7 @@ impl<T> Channel<T> { } /// Writes a message into the packet. - pub unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { + pub(crate) unsafe fn write(&self, token: &mut Token, msg: T) -> Result<(), T> { // If there is no packet, the channel is disconnected. if token.zero == 0 { return Err(msg); @@ -157,7 +157,7 @@ impl<T> Channel<T> { } /// Reads a message from the packet. - pub unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { + pub(crate) unsafe fn read(&self, token: &mut Token) -> Result<T, ()> { // If there is no packet, the channel is disconnected. if token.zero == 0 { return Err(()); @@ -183,7 +183,7 @@ impl<T> Channel<T> { } /// Attempts to send a message into the channel. - pub fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { + pub(crate) fn try_send(&self, msg: T) -> Result<(), TrySendError<T>> { let token = &mut Token::default(); let mut inner = self.inner.lock(); @@ -203,7 +203,11 @@ impl<T> Channel<T> { } /// Sends a message into the channel. - pub fn send(&self, msg: T, deadline: Option<Instant>) -> Result<(), SendTimeoutError<T>> { + pub(crate) fn send( + &self, + msg: T, + deadline: Option<Instant>, + ) -> Result<(), SendTimeoutError<T>> { let token = &mut Token::default(); let mut inner = self.inner.lock(); @@ -256,7 +260,7 @@ impl<T> Channel<T> { } /// Attempts to receive a message without blocking. - pub fn try_recv(&self) -> Result<T, TryRecvError> { + pub(crate) fn try_recv(&self) -> Result<T, TryRecvError> { let token = &mut Token::default(); let mut inner = self.inner.lock(); @@ -273,7 +277,7 @@ impl<T> Channel<T> { } /// Receives a message from the channel. - pub fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { + pub(crate) fn recv(&self, deadline: Option<Instant>) -> Result<T, RecvTimeoutError> { let token = &mut Token::default(); let mut inner = self.inner.lock(); @@ -325,7 +329,7 @@ impl<T> Channel<T> { /// Disconnects the channel and wakes up all blocked senders and receivers. /// /// Returns `true` if this call disconnected the channel. - pub fn disconnect(&self) -> bool { + pub(crate) fn disconnect(&self) -> bool { let mut inner = self.inner.lock(); if !inner.is_disconnected { @@ -339,31 +343,32 @@ impl<T> Channel<T> { } /// Returns the current number of messages inside the channel. - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { 0 } /// Returns the capacity of the channel. - pub fn capacity(&self) -> Option<usize> { + #[allow(clippy::unnecessary_wraps)] // This is intentional. + pub(crate) fn capacity(&self) -> Option<usize> { Some(0) } /// Returns `true` if the channel is empty. - pub fn is_empty(&self) -> bool { + pub(crate) fn is_empty(&self) -> bool { true } /// Returns `true` if the channel is full. - pub fn is_full(&self) -> bool { + pub(crate) fn is_full(&self) -> bool { true } } /// Receiver handle to a channel. -pub struct Receiver<'a, T>(&'a Channel<T>); +pub(crate) struct Receiver<'a, T>(&'a Channel<T>); /// Sender handle to a channel. -pub struct Sender<'a, T>(&'a Channel<T>); +pub(crate) struct Sender<'a, T>(&'a Channel<T>); impl<T> SelectHandle for Receiver<'_, T> { fn try_select(&self, token: &mut Token) -> bool { diff --git a/third_party/rust/crossbeam-channel/src/lib.rs b/third_party/rust/crossbeam-channel/src/lib.rs index e08ac08f9088e64c61aa742277b1fea2629d20b7..cc1ef112f9cce971affcd0b84d7317725626c215 100644 --- a/third_party/rust/crossbeam-channel/src/lib.rs +++ b/third_party/rust/crossbeam-channel/src/lib.rs @@ -294,7 +294,7 @@ //! //! * [`after`] creates a channel that delivers a single message after a certain duration of time. //! * [`tick`] creates a channel that delivers messages periodically. -//! * [`never`] creates a channel that never delivers messages. +//! * [`never`](never()) creates a channel that never delivers messages. //! //! These channels are very efficient because messages get lazily generated on receive operations. //! @@ -328,10 +328,13 @@ allow(dead_code, unused_assignments, unused_variables) ) ))] -#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)] +#![warn( + missing_docs, + missing_debug_implementations, + rust_2018_idioms, + unreachable_pub +)] #![cfg_attr(not(feature = "std"), no_std)] -// matches! requires Rust 1.42 -#![allow(clippy::match_like_matches_macro)] use cfg_if::cfg_if; diff --git a/third_party/rust/crossbeam-channel/src/select.rs b/third_party/rust/crossbeam-channel/src/select.rs index 1488f80d5f46915c18b666371e0b774cac533016..5259328b805762a31606e3c0696660bcbb5344ad 100644 --- a/third_party/rust/crossbeam-channel/src/select.rs +++ b/third_party/rust/crossbeam-channel/src/select.rs @@ -486,7 +486,7 @@ pub fn select_timeout<'a>( /// Blocks until a given deadline, or until one of the operations becomes ready and selects it. #[inline] -pub fn select_deadline<'a>( +pub(crate) fn select_deadline<'a>( handles: &mut [(&'a dyn SelectHandle, usize, *const u8)], deadline: Instant, ) -> Result<SelectedOperation<'a>, SelectTimeoutError> { @@ -864,9 +864,6 @@ impl<'a> Select<'a> { /// The selected operation must be completed with [`SelectedOperation::send`] /// or [`SelectedOperation::recv`]. /// - /// [`SelectedOperation::send`]: struct.SelectedOperation.html#method.send - /// [`SelectedOperation::recv`]: struct.SelectedOperation.html#method.recv - /// /// # Examples /// /// ``` diff --git a/third_party/rust/crossbeam-channel/src/utils.rs b/third_party/rust/crossbeam-channel/src/utils.rs index 3fe171b2e45291dae52e34756c92dfb16c3b84a2..557b6a0d771d2611fc55241dbf0c7ebd7a73f09c 100644 --- a/third_party/rust/crossbeam-channel/src/utils.rs +++ b/third_party/rust/crossbeam-channel/src/utils.rs @@ -10,7 +10,7 @@ use std::time::{Duration, Instant}; use crossbeam_utils::Backoff; /// Randomly shuffles a slice. -pub fn shuffle<T>(v: &mut [T]) { +pub(crate) fn shuffle<T>(v: &mut [T]) { let len = v.len(); if len <= 1 { return; @@ -46,7 +46,7 @@ pub fn shuffle<T>(v: &mut [T]) { } /// Sleeps until the deadline, or forever if the deadline isn't specified. -pub fn sleep_until(deadline: Option<Instant>) { +pub(crate) fn sleep_until(deadline: Option<Instant>) { loop { match deadline { None => thread::sleep(Duration::from_secs(1000)), @@ -62,14 +62,14 @@ pub fn sleep_until(deadline: Option<Instant>) { } /// A simple spinlock. -pub struct Spinlock<T> { +pub(crate) struct Spinlock<T> { flag: AtomicBool, value: UnsafeCell<T>, } impl<T> Spinlock<T> { /// Returns a new spinlock initialized with `value`. - pub fn new(value: T) -> Spinlock<T> { + pub(crate) fn new(value: T) -> Spinlock<T> { Spinlock { flag: AtomicBool::new(false), value: UnsafeCell::new(value), @@ -77,7 +77,7 @@ impl<T> Spinlock<T> { } /// Locks the spinlock. - pub fn lock(&self) -> SpinlockGuard<'_, T> { + pub(crate) fn lock(&self) -> SpinlockGuard<'_, T> { let backoff = Backoff::new(); while self.flag.swap(true, Ordering::Acquire) { backoff.snooze(); @@ -87,7 +87,7 @@ impl<T> Spinlock<T> { } /// A guard holding a spinlock locked. -pub struct SpinlockGuard<'a, T> { +pub(crate) struct SpinlockGuard<'a, T> { parent: &'a Spinlock<T>, } diff --git a/third_party/rust/crossbeam-channel/src/waker.rs b/third_party/rust/crossbeam-channel/src/waker.rs index 3d0af2616cc4405e54b276a5005f7e82ca0bdeb6..62defa2e18439dc4216807c9147fca2438975857 100644 --- a/third_party/rust/crossbeam-channel/src/waker.rs +++ b/third_party/rust/crossbeam-channel/src/waker.rs @@ -8,22 +8,22 @@ use crate::select::{Operation, Selected}; use crate::utils::Spinlock; /// Represents a thread blocked on a specific channel operation. -pub struct Entry { +pub(crate) struct Entry { /// The operation. - pub oper: Operation, + pub(crate) oper: Operation, /// Optional packet. - pub packet: usize, + pub(crate) packet: usize, /// Context associated with the thread owning this operation. - pub cx: Context, + pub(crate) cx: Context, } /// A queue of threads blocked on channel operations. /// /// This data structure is used by threads to register blocking operations and get woken up once /// an operation becomes ready. -pub struct Waker { +pub(crate) struct Waker { /// A list of select operations. selectors: Vec<Entry>, @@ -34,7 +34,7 @@ pub struct Waker { impl Waker { /// Creates a new `Waker`. #[inline] - pub fn new() -> Self { + pub(crate) fn new() -> Self { Waker { selectors: Vec::new(), observers: Vec::new(), @@ -43,13 +43,13 @@ impl Waker { /// Registers a select operation. #[inline] - pub fn register(&mut self, oper: Operation, cx: &Context) { + pub(crate) fn register(&mut self, oper: Operation, cx: &Context) { self.register_with_packet(oper, 0, cx); } /// Registers a select operation and a packet. #[inline] - pub fn register_with_packet(&mut self, oper: Operation, packet: usize, cx: &Context) { + pub(crate) fn register_with_packet(&mut self, oper: Operation, packet: usize, cx: &Context) { self.selectors.push(Entry { oper, packet, @@ -59,7 +59,7 @@ impl Waker { /// Unregisters a select operation. #[inline] - pub fn unregister(&mut self, oper: Operation) -> Option<Entry> { + pub(crate) fn unregister(&mut self, oper: Operation) -> Option<Entry> { if let Some((i, _)) = self .selectors .iter() @@ -75,7 +75,7 @@ impl Waker { /// Attempts to find another thread's entry, select the operation, and wake it up. #[inline] - pub fn try_select(&mut self) -> Option<Entry> { + pub(crate) fn try_select(&mut self) -> Option<Entry> { let mut entry = None; if !self.selectors.is_empty() { @@ -108,7 +108,7 @@ impl Waker { /// Returns `true` if there is an entry which can be selected by the current thread. #[inline] - pub fn can_select(&self) -> bool { + pub(crate) fn can_select(&self) -> bool { if self.selectors.is_empty() { false } else { @@ -122,7 +122,7 @@ impl Waker { /// Registers an operation waiting to be ready. #[inline] - pub fn watch(&mut self, oper: Operation, cx: &Context) { + pub(crate) fn watch(&mut self, oper: Operation, cx: &Context) { self.observers.push(Entry { oper, packet: 0, @@ -132,13 +132,13 @@ impl Waker { /// Unregisters an operation waiting to be ready. #[inline] - pub fn unwatch(&mut self, oper: Operation) { + pub(crate) fn unwatch(&mut self, oper: Operation) { self.observers.retain(|e| e.oper != oper); } /// Notifies all operations waiting to be ready. #[inline] - pub fn notify(&mut self) { + pub(crate) fn notify(&mut self) { for entry in self.observers.drain(..) { if entry.cx.try_select(Selected::Operation(entry.oper)).is_ok() { entry.cx.unpark(); @@ -148,7 +148,7 @@ impl Waker { /// Notifies all registered operations that the channel is disconnected. #[inline] - pub fn disconnect(&mut self) { + pub(crate) fn disconnect(&mut self) { for entry in self.selectors.iter() { if entry.cx.try_select(Selected::Disconnected).is_ok() { // Wake the thread up. @@ -175,7 +175,7 @@ impl Drop for Waker { /// A waker that can be shared among threads without locking. /// /// This is a simple wrapper around `Waker` that internally uses a mutex for synchronization. -pub struct SyncWaker { +pub(crate) struct SyncWaker { /// The inner `Waker`. inner: Spinlock<Waker>, @@ -186,7 +186,7 @@ pub struct SyncWaker { impl SyncWaker { /// Creates a new `SyncWaker`. #[inline] - pub fn new() -> Self { + pub(crate) fn new() -> Self { SyncWaker { inner: Spinlock::new(Waker::new()), is_empty: AtomicBool::new(true), @@ -195,7 +195,7 @@ impl SyncWaker { /// Registers the current thread with an operation. #[inline] - pub fn register(&self, oper: Operation, cx: &Context) { + pub(crate) fn register(&self, oper: Operation, cx: &Context) { let mut inner = self.inner.lock(); inner.register(oper, cx); self.is_empty.store( @@ -206,7 +206,7 @@ impl SyncWaker { /// Unregisters an operation previously registered by the current thread. #[inline] - pub fn unregister(&self, oper: Operation) -> Option<Entry> { + pub(crate) fn unregister(&self, oper: Operation) -> Option<Entry> { let mut inner = self.inner.lock(); let entry = inner.unregister(oper); self.is_empty.store( @@ -218,7 +218,7 @@ impl SyncWaker { /// Attempts to find one thread (not the current one), select its operation, and wake it up. #[inline] - pub fn notify(&self) { + pub(crate) fn notify(&self) { if !self.is_empty.load(Ordering::SeqCst) { let mut inner = self.inner.lock(); if !self.is_empty.load(Ordering::SeqCst) { @@ -234,7 +234,7 @@ impl SyncWaker { /// Registers an operation waiting to be ready. #[inline] - pub fn watch(&self, oper: Operation, cx: &Context) { + pub(crate) fn watch(&self, oper: Operation, cx: &Context) { let mut inner = self.inner.lock(); inner.watch(oper, cx); self.is_empty.store( @@ -245,7 +245,7 @@ impl SyncWaker { /// Unregisters an operation waiting to be ready. #[inline] - pub fn unwatch(&self, oper: Operation) { + pub(crate) fn unwatch(&self, oper: Operation) { let mut inner = self.inner.lock(); inner.unwatch(oper); self.is_empty.store( @@ -256,7 +256,7 @@ impl SyncWaker { /// Notifies all threads that the channel is disconnected. #[inline] - pub fn disconnect(&self) { + pub(crate) fn disconnect(&self) { let mut inner = self.inner.lock(); inner.disconnect(); self.is_empty.store( diff --git a/third_party/rust/crossbeam-channel/tests/array.rs b/third_party/rust/crossbeam-channel/tests/array.rs index a7ae323d91af0f70c14798e872804e2798e197c7..15c30a50b16a34181f33000a39e8fe1da71e553a 100644 --- a/third_party/rust/crossbeam-channel/tests/array.rs +++ b/third_party/rust/crossbeam-channel/tests/array.rs @@ -497,8 +497,8 @@ fn drops() { let mut rng = thread_rng(); for _ in 0..RUNS { - let steps = rng.gen_range(0, 10_000); - let additional = rng.gen_range(0, 50); + let steps = rng.gen_range(0..10_000); + let additional = rng.gen_range(0..50); DROPS.store(0, Ordering::SeqCst); let (s, r) = bounded::<DropCounter>(50); diff --git a/third_party/rust/crossbeam-channel/tests/golang.rs b/third_party/rust/crossbeam-channel/tests/golang.rs index 69a9315a0a58c583d4242bd86e9adcd59a8000c0..cd7001326f685ad35a19a0b13dcaa6cfb3c3ef3a 100644 --- a/third_party/rust/crossbeam-channel/tests/golang.rs +++ b/third_party/rust/crossbeam-channel/tests/golang.rs @@ -315,7 +315,7 @@ mod fifo { fn chain(ch: Chan<i32>, val: i32, inp: Chan<i32>, out: Chan<i32>) { inp.recv(); if ch.recv() != Some(val) { - panic!(val); + panic!("{}", val); } out.send(1); } @@ -1507,5 +1507,58 @@ mod chan { // https://github.com/golang/go/blob/master/test/ken/chan1.go mod chan1 { - // TODO + use super::*; + + // sent messages + const N: usize = 1000; + // receiving "goroutines" + const M: usize = 10; + // channel buffering + const W: usize = 2; + + fn r(c: Chan<usize>, m: usize, h: Arc<Mutex<[usize; N]>>) { + loop { + select! { + recv(c.rx()) -> rr => { + let r = rr.unwrap(); + let mut data = h.lock().unwrap(); + if data[r] != 1 { + println!("r\nm={}\nr={}\nh={}\n", m, r, data[r]); + panic!("fail") + } + data[r] = 2; + } + } + } + } + + fn s(c: Chan<usize>, h: Arc<Mutex<[usize; N]>>) { + for n in 0..N { + let r = n; + let mut data = h.lock().unwrap(); + if data[r] != 0 { + println!("s"); + panic!("fail"); + } + data[r] = 1; + // https://github.com/crossbeam-rs/crossbeam/pull/615#discussion_r550281094 + drop(data); + c.send(r); + } + } + + #[test] + fn main() { + let h = Arc::new(Mutex::new([0usize; N])); + let c = make::<usize>(W); + for m in 0..M { + go!(c, h, { + r(c, m, h); + }); + thread::yield_now(); + } + thread::yield_now(); + thread::yield_now(); + s(c, h); + } } diff --git a/third_party/rust/crossbeam-channel/tests/list.rs b/third_party/rust/crossbeam-channel/tests/list.rs index 8b841054067c5dc0ceac120d8884cc870edca34e..f166a19815f5a548da40bd2cfd134e1d70390dd2 100644 --- a/third_party/rust/crossbeam-channel/tests/list.rs +++ b/third_party/rust/crossbeam-channel/tests/list.rs @@ -387,8 +387,8 @@ fn drops() { let mut rng = thread_rng(); for _ in 0..100 { - let steps = rng.gen_range(0, 10_000); - let additional = rng.gen_range(0, 1000); + let steps = rng.gen_range(0..10_000); + let additional = rng.gen_range(0..1000); DROPS.store(0, Ordering::SeqCst); let (s, r) = unbounded::<DropCounter>(); diff --git a/third_party/rust/crossbeam-channel/tests/ready.rs b/third_party/rust/crossbeam-channel/tests/ready.rs index 700f487e04174c113a4739ec92ce8606198a805a..6779694a978a920a47f74d0c0e1a70f588307536 100644 --- a/third_party/rust/crossbeam-channel/tests/ready.rs +++ b/third_party/rust/crossbeam-channel/tests/ready.rs @@ -606,8 +606,7 @@ fn stress_timeout_two_threads() { thread::sleep(ms(500)); } - let done = false; - while !done { + loop { let mut sel = Select::new(); sel.send(&s); match sel.ready_timeout(ms(100)) { @@ -628,15 +627,14 @@ fn stress_timeout_two_threads() { thread::sleep(ms(500)); } - let mut done = false; - while !done { + loop { let mut sel = Select::new(); sel.recv(&r); match sel.ready_timeout(ms(100)) { Err(_) => {} Ok(0) => { assert_eq!(r.try_recv(), Ok(i)); - done = true; + break; } Ok(_) => panic!(), } diff --git a/third_party/rust/crossbeam-channel/tests/select.rs b/third_party/rust/crossbeam-channel/tests/select.rs index 4cf08b6a6282e2ba94d038ace4e0b8aae8b139be..fcc291ef382994a7a3e51d30240e1566b9dbfc55 100644 --- a/third_party/rust/crossbeam-channel/tests/select.rs +++ b/third_party/rust/crossbeam-channel/tests/select.rs @@ -809,8 +809,7 @@ fn stress_timeout_two_threads() { thread::sleep(ms(500)); } - let done = false; - while !done { + loop { let mut sel = Select::new(); let oper1 = sel.send(&s); let oper = sel.select_timeout(ms(100)); @@ -834,8 +833,7 @@ fn stress_timeout_two_threads() { thread::sleep(ms(500)); } - let mut done = false; - while !done { + loop { let mut sel = Select::new(); let oper1 = sel.recv(&r); let oper = sel.select_timeout(ms(100)); @@ -844,7 +842,7 @@ fn stress_timeout_two_threads() { Ok(oper) => match oper.index() { ix if ix == oper1 => { assert_eq!(oper.recv(&r), Ok(i)); - done = true; + break; } _ => unreachable!(), }, diff --git a/third_party/rust/crossbeam-channel/tests/tick.rs b/third_party/rust/crossbeam-channel/tests/tick.rs index 5dc87306ff357681a138d19b84f0ff4fa9ca7acd..1273f64b5b044246e6a78727b04c426b958d7f0f 100644 --- a/third_party/rust/crossbeam-channel/tests/tick.rs +++ b/third_party/rust/crossbeam-channel/tests/tick.rs @@ -127,6 +127,7 @@ fn recv() { assert_eq!(r.try_recv(), Err(TryRecvError::Empty)); } +#[cfg(not(crossbeam_sanitize))] // TODO: assertions failed due to tsan is slow #[test] fn recv_timeout() { let start = Instant::now(); @@ -251,6 +252,7 @@ fn select() { assert_eq!(hits.load(Ordering::SeqCst), 8); } +#[cfg(not(crossbeam_sanitize))] // TODO: assertions failed due to tsan is slow #[test] fn ready() { const THREADS: usize = 4; diff --git a/third_party/rust/crossbeam-channel/tests/zero.rs b/third_party/rust/crossbeam-channel/tests/zero.rs index 66dcc1eeb6614370789ed4952e83abb5f2f86e98..1dd39e1817399026f2d1e69d718e2d7871392499 100644 --- a/third_party/rust/crossbeam-channel/tests/zero.rs +++ b/third_party/rust/crossbeam-channel/tests/zero.rs @@ -399,7 +399,7 @@ fn drops() { let mut rng = thread_rng(); for _ in 0..100 { - let steps = rng.gen_range(0, 3_000); + let steps = rng.gen_range(0..3_000); DROPS.store(0, Ordering::SeqCst); let (s, r) = bounded::<DropCounter>(0); diff --git a/third_party/rust/crossbeam-deque/.cargo-checksum.json b/third_party/rust/crossbeam-deque/.cargo-checksum.json index 76bc64238e6ad4ba01ee068b7c4d52c3c2ae2635..202fdfe8de291b1e7b0a8797f18326f445257413 100644 --- a/third_party/rust/crossbeam-deque/.cargo-checksum.json +++ b/third_party/rust/crossbeam-deque/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"2a351fc7603e0cf7a66c305fa9429f7871113605427a8e43f701b71854cc2181","Cargo.toml":"381453938bdca74a67ac96146f8c544b30aa62293e47eaa6447a9d9bb03668eb","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"c1e2f0e311bab5c2b82a9346e7b2fdaf17050a66913aad57fac40665fb65bb7b","src/lib.rs":"279ea1d9e7e72488e2590cb88fb14bdf9b8250676adb27d19efd281c91e63680","tests/fifo.rs":"7546ce471330a9d928a54f6ca41ddd36e9f4999852fdc4719bf9b24122a1c15f","tests/injector.rs":"c9107b437f790dbfab333f94d7211df29bb9a868d2d86304ad9fd7fa8db57d0a","tests/lifo.rs":"264967bc868870211e12a826f448a6d9e19ab5f7cc0e0bde86496cf76bb96e56","tests/steal.rs":"519549c18429db563c5238d7147e733901336943ca099669af2b553933b82694"},"package":"c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca"} \ No newline at end of file +{"files":{"CHANGELOG.md":"f917b6e83aed21fcdb7615602b74377374144b6e075d1d96e9dac8c266795cab","Cargo.toml":"d160e0a9f564fa20e503f81a837057b09bdc8632d8b71c6a3d4a0a67c0bcaa21","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"c1e2f0e311bab5c2b82a9346e7b2fdaf17050a66913aad57fac40665fb65bb7b","src/lib.rs":"78b31a8d769607304d5d6250f8b06f257160b7c8b43ced5ef40f4ec3a51e076b","tests/fifo.rs":"7546ce471330a9d928a54f6ca41ddd36e9f4999852fdc4719bf9b24122a1c15f","tests/injector.rs":"c9107b437f790dbfab333f94d7211df29bb9a868d2d86304ad9fd7fa8db57d0a","tests/lifo.rs":"264967bc868870211e12a826f448a6d9e19ab5f7cc0e0bde86496cf76bb96e56","tests/steal.rs":"519549c18429db563c5238d7147e733901336943ca099669af2b553933b82694"},"package":"9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"} \ No newline at end of file diff --git a/third_party/rust/crossbeam-deque/CHANGELOG.md b/third_party/rust/crossbeam-deque/CHANGELOG.md index a9e1c79a8837ebd8d9c1eeee0a1d134136b2f945..54e9ae41fcbd083d92a0ddf9ab3777b11e93c8bf 100644 --- a/third_party/rust/crossbeam-deque/CHANGELOG.md +++ b/third_party/rust/crossbeam-deque/CHANGELOG.md @@ -1,3 +1,8 @@ +# Version 0.7.3 + +- Stop stealing from the same deque. (#448) +- Fix unsoundness issues by adopting `MaybeUninit`. (#458) + # Version 0.7.2 - Bump `crossbeam-epoch` to `0.8`. diff --git a/third_party/rust/crossbeam-deque/Cargo.toml b/third_party/rust/crossbeam-deque/Cargo.toml index 2ce052337fd6a165f8f22f8021eb74c76f60d0aa..0cf94c2df5732f6fa9a4427a72e694127b8ddca4 100644 --- a/third_party/rust/crossbeam-deque/Cargo.toml +++ b/third_party/rust/crossbeam-deque/Cargo.toml @@ -12,7 +12,7 @@ [package] name = "crossbeam-deque" -version = "0.7.2" +version = "0.7.3" authors = ["The Crossbeam Project Developers"] description = "Concurrent work-stealing deque" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-deque" @@ -27,5 +27,8 @@ version = "0.8" [dependencies.crossbeam-utils] version = "0.7" + +[dependencies.maybe-uninit] +version = "2.0.0" [dev-dependencies.rand] version = "0.6" diff --git a/third_party/rust/crossbeam-deque/src/lib.rs b/third_party/rust/crossbeam-deque/src/lib.rs index 1fdf00e3dccacd306b0af74f086199db74202cac..59004174d83b6c52a9ad5fba2d4fefc4c2301b07 100644 --- a/third_party/rust/crossbeam-deque/src/lib.rs +++ b/third_party/rust/crossbeam-deque/src/lib.rs @@ -92,12 +92,14 @@ extern crate crossbeam_epoch as epoch; extern crate crossbeam_utils as utils; +extern crate maybe_uninit; + use std::cell::{Cell, UnsafeCell}; use std::cmp; use std::fmt; use std::iter::FromIterator; use std::marker::PhantomData; -use std::mem::{self, ManuallyDrop}; +use std::mem; use std::ptr; use std::sync::atomic::{self, AtomicIsize, AtomicPtr, AtomicUsize, Ordering}; use std::sync::Arc; @@ -105,6 +107,8 @@ use std::sync::Arc; use epoch::{Atomic, Owned}; use utils::{Backoff, CachePadded}; +use maybe_uninit::MaybeUninit; + // Minimum buffer capacity. const MIN_CAP: usize = 64; // Maximum number of tasks that can be stolen in `steal_batch()` and `steal_batch_and_pop()`. @@ -218,7 +222,7 @@ impl<T> Drop for Inner<T> { // Go through the buffer from front to back and drop all tasks in the queue. let mut i = f; while i != b { - ptr::drop_in_place(buffer.deref().at(i)); + buffer.deref().at(i).drop_in_place(); i = i.wrapping_add(1); } @@ -745,6 +749,14 @@ impl<T> Stealer<T> { /// assert_eq!(w2.pop(), Some(2)); /// ``` pub fn steal_batch(&self, dest: &Worker<T>) -> Steal<()> { + if Arc::ptr_eq(&self.inner, &dest.inner) { + if dest.is_empty() { + return Steal::Empty; + } else { + return Steal::Success(()); + } + } + // Load the front index. let mut f = self.inner.front.load(Ordering::Acquire); @@ -922,6 +934,13 @@ impl<T> Stealer<T> { /// assert_eq!(w2.pop(), Some(2)); /// ``` pub fn steal_batch_and_pop(&self, dest: &Worker<T>) -> Steal<T> { + if Arc::ptr_eq(&self.inner, &dest.inner) { + match dest.pop() { + None => return Steal::Empty, + Some(task) => return Steal::Success(task), + } + } + // Load the front index. let mut f = self.inner.front.load(Ordering::Acquire); @@ -1125,7 +1144,7 @@ const HAS_NEXT: usize = 1; /// A slot in a block. struct Slot<T> { /// The task. - task: UnsafeCell<ManuallyDrop<T>>, + task: UnsafeCell<MaybeUninit<T>>, /// The state of the slot. state: AtomicUsize, @@ -1155,7 +1174,13 @@ struct Block<T> { impl<T> Block<T> { /// Creates an empty block that starts at `start_index`. fn new() -> Block<T> { - unsafe { mem::zeroed() } + // SAFETY: This is safe because: + // [1] `Block::next` (AtomicPtr) may be safely zero initialized. + // [2] `Block::slots` (Array) may be safely zero initialized because of [3, 4]. + // [3] `Slot::task` (UnsafeCell) may be safely zero initialized because it + // holds a MaybeUninit. + // [4] `Slot::state` (AtomicUsize) may be safely zero initialized. + unsafe { MaybeUninit::zeroed().assume_init() } } /// Waits until the next pointer is set. @@ -1314,7 +1339,7 @@ impl<T> Injector<T> { // Write the task into the slot. let slot = (*block).slots.get_unchecked(offset); - slot.task.get().write(ManuallyDrop::new(task)); + slot.task.get().write(MaybeUninit::new(task)); slot.state.fetch_or(WRITE, Ordering::Release); return; @@ -1407,8 +1432,7 @@ impl<T> Injector<T> { // Read the task. let slot = (*block).slots.get_unchecked(offset); slot.wait_write(); - let m = slot.task.get().read(); - let task = ManuallyDrop::into_inner(m); + let task = slot.task.get().read().assume_init(); // Destroy the block if we've reached the end, or if another thread wanted to destroy // but couldn't because we were busy reading from the slot. @@ -1533,8 +1557,7 @@ impl<T> Injector<T> { // Read the task. let slot = (*block).slots.get_unchecked(offset + i); slot.wait_write(); - let m = slot.task.get().read(); - let task = ManuallyDrop::into_inner(m); + let task = slot.task.get().read().assume_init(); // Write it into the destination queue. dest_buffer.write(dest_b.wrapping_add(i as isize), task); @@ -1546,8 +1569,7 @@ impl<T> Injector<T> { // Read the task. let slot = (*block).slots.get_unchecked(offset + i); slot.wait_write(); - let m = slot.task.get().read(); - let task = ManuallyDrop::into_inner(m); + let task = slot.task.get().read().assume_init(); // Write it into the destination queue. dest_buffer.write(dest_b.wrapping_add((batch_size - 1 - i) as isize), task); @@ -1689,8 +1711,7 @@ impl<T> Injector<T> { // Read the task. let slot = (*block).slots.get_unchecked(offset); slot.wait_write(); - let m = slot.task.get().read(); - let task = ManuallyDrop::into_inner(m); + let task = slot.task.get().read().assume_init(); match dest.flavor { Flavor::Fifo => { @@ -1699,8 +1720,7 @@ impl<T> Injector<T> { // Read the task. let slot = (*block).slots.get_unchecked(offset + i + 1); slot.wait_write(); - let m = slot.task.get().read(); - let task = ManuallyDrop::into_inner(m); + let task = slot.task.get().read().assume_init(); // Write it into the destination queue. dest_buffer.write(dest_b.wrapping_add(i as isize), task); @@ -1713,8 +1733,7 @@ impl<T> Injector<T> { // Read the task. let slot = (*block).slots.get_unchecked(offset + i + 1); slot.wait_write(); - let m = slot.task.get().read(); - let task = ManuallyDrop::into_inner(m); + let task = slot.task.get().read().assume_init(); // Write it into the destination queue. dest_buffer.write(dest_b.wrapping_add((batch_size - 1 - i) as isize), task); @@ -1789,7 +1808,8 @@ impl<T> Drop for Injector<T> { if offset < BLOCK_CAP { // Drop the task in the slot. let slot = (*block).slots.get_unchecked(offset); - ManuallyDrop::drop(&mut *(*slot).task.get()); + let p = &mut *slot.task.get(); + p.as_mut_ptr().drop_in_place(); } else { // Deallocate the block and move to the next one. let next = (*block).next.load(Ordering::Relaxed); diff --git a/third_party/rust/crossbeam-epoch/.cargo-checksum.json b/third_party/rust/crossbeam-epoch/.cargo-checksum.json index d42d88919de49d68c8094d4d26e8bb549921fa3c..231351ab6983df9fcaefd72cb339be36011e7940 100644 --- a/third_party/rust/crossbeam-epoch/.cargo-checksum.json +++ b/third_party/rust/crossbeam-epoch/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"1d5defc0cddbd56dab9aad0c52a6101e2ae38a04703622b70822af4162b422b6","Cargo.lock":"dd8ea5cc92174990a2726564d8ea7d4cf1dcbc0e5775a5a8f07b854bcb25e27d","Cargo.toml":"802dbfef2329ab8d39ce1602e93f41403e2c297521e702e4278cf88df106f3a4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"30bed3b95612935f87903eeb37dfd09e133e4c064a66eb8b5681eaf97128c8e9","benches/defer.rs":"a4b17e7b96bef2f268c76925cfa58744b81504146426fab6f781ff0b2f666f2b","benches/flush.rs":"1d93ac40cb78bf2c55332869d4f7d1b283571bff4a0c6dbe245f02dd65e8e1d8","benches/pin.rs":"dd937ecfc8d7353995d438a7f4be383e91c002e9ee6acd4caa703bb340c97383","build.rs":"825c47ae19028dc4b28101ec71c04e7e41b8b185f6ecbeacee223596524c86ad","examples/sanitize.rs":"90f80709cd620e994f699d84ab9ce88f8552500d08bac64d60def5792460495a","examples/treiber_stack.rs":"b5d3bafa6d57af435b00d04145572a51ea871f64ff2c23ba544054c4c4145d65","src/atomic.rs":"53c29c8df6a90e2cd3d7747f7ebfe604087966c8ea6473ff2593bdd495f43951","src/collector.rs":"a783049d3cb22989ec978366fd865f31562b0acbfbd0bc9ff9b600ceaa5ffa87","src/default.rs":"6afda8fd141ad594bed62baeb73f2e97c5ef33b051969a542bb908946fe39dd1","src/deferred.rs":"883067dd60b108baacaafc9024833c0ec08c6b5649b60c030ab9a59e952ccd06","src/epoch.rs":"76dd63356d5bc52e741883d39abb636e4ccb04d20499fb2a0ce797bb81aa4e91","src/guard.rs":"486efbc061b7f402f4c8a96abd1889aff4b28eb10347b65e538c39d539d919ad","src/internal.rs":"5b09661b12d93412140b2ee186ebb304891374e4c512b5bbc97cd015ec34c493","src/lib.rs":"e55b6c418970e3bbd265a21b9beaf2d8254f7f7799e9954edf4486666869e2aa","src/sync/list.rs":"43e09e9cf79d7cf95b5110051de9dd47ab7761e3bc90ea3be16c4cbabce6d4be","src/sync/mod.rs":"2da979ca3a2293f7626a2e6a9ab2fad758d92e3d2bed6cc712ef59eeeea87eab","src/sync/queue.rs":"266036a201222fe46b6674fa789b96dd8c385bf2c37135799fb9ba1fba53049a"},"package":"5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"} \ No newline at end of file +{"files":{"CHANGELOG.md":"6f63ac1fc542b3aac4b43cdcd4c1ec549e2afb50c03836d3ca10468531684b5f","Cargo.lock":"cde1950d5785b0962e84cd5e98ce6bbbc981c606c2e73601f060d488ec2bca5f","Cargo.toml":"212414f7fad97f2b0eabff851d380ea75d043d3b16266a54e4724da588cd648d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"30bed3b95612935f87903eeb37dfd09e133e4c064a66eb8b5681eaf97128c8e9","benches/defer.rs":"a4b17e7b96bef2f268c76925cfa58744b81504146426fab6f781ff0b2f666f2b","benches/flush.rs":"1d93ac40cb78bf2c55332869d4f7d1b283571bff4a0c6dbe245f02dd65e8e1d8","benches/pin.rs":"dd937ecfc8d7353995d438a7f4be383e91c002e9ee6acd4caa703bb340c97383","build.rs":"825c47ae19028dc4b28101ec71c04e7e41b8b185f6ecbeacee223596524c86ad","examples/sanitize.rs":"90f80709cd620e994f699d84ab9ce88f8552500d08bac64d60def5792460495a","examples/treiber_stack.rs":"b5d3bafa6d57af435b00d04145572a51ea871f64ff2c23ba544054c4c4145d65","src/atomic.rs":"53c29c8df6a90e2cd3d7747f7ebfe604087966c8ea6473ff2593bdd495f43951","src/collector.rs":"a783049d3cb22989ec978366fd865f31562b0acbfbd0bc9ff9b600ceaa5ffa87","src/default.rs":"7fec6d381ae0efab8c1539c78588f99b8fcd6551ac67740fcfd45be3405ca53a","src/deferred.rs":"2793f8a5d271e7a787f7e99bdff7b07488742704bd47721459f0bb5085e6b3ea","src/epoch.rs":"76dd63356d5bc52e741883d39abb636e4ccb04d20499fb2a0ce797bb81aa4e91","src/guard.rs":"486efbc061b7f402f4c8a96abd1889aff4b28eb10347b65e538c39d539d919ad","src/internal.rs":"82030dc0cdc30741b2ca840455d2074e9fc0b9186c043d18bcf54bab093ce083","src/lib.rs":"c6c94853766d307eb36f75e1f4feabe2b4b13659d20e11ea9b82b6472363ce9f","src/sync/list.rs":"ef59984162102d01279f6eb7ded52d923933287dd4d7785b758b049768a3c118","src/sync/mod.rs":"2da979ca3a2293f7626a2e6a9ab2fad758d92e3d2bed6cc712ef59eeeea87eab","src/sync/queue.rs":"89390788a53ee932dcd92221cd2a8db25fd52a1e0b2b1fb9bd4230dec9eadcac"},"package":"058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"} \ No newline at end of file diff --git a/third_party/rust/crossbeam-epoch/CHANGELOG.md b/third_party/rust/crossbeam-epoch/CHANGELOG.md index e4aa1fdb29649ba50c0e635ad8bf8c1754e107f1..07e64efebf3230965e3911183b57ffc847bbd4b0 100644 --- a/third_party/rust/crossbeam-epoch/CHANGELOG.md +++ b/third_party/rust/crossbeam-epoch/CHANGELOG.md @@ -1,3 +1,15 @@ +# Version 0.8.2 + +- Fix bug in release (yanking 0.8.1) + +# Version 0.8.1 + +- Bump `autocfg` dependency to version 1.0. (#460) +- Reduce stall in list iteration. (#376) +- Stop stealing from the same deque. (#448) +- Fix unsoundness issues by adopting `MaybeUninit`. (#458) +- Fix use-after-free in lock-free queue. (#466) + # Version 0.8.0 - Bump the minimum required version to 1.28. diff --git a/third_party/rust/crossbeam-epoch/Cargo.lock b/third_party/rust/crossbeam-epoch/Cargo.lock index 9f19f55e358f8d7f568dce72dfc033ececc524c6..d3f8334df2542aacae2433cd91d016925d779460 100644 --- a/third_party/rust/crossbeam-epoch/Cargo.lock +++ b/third_party/rust/crossbeam-epoch/Cargo.lock @@ -5,6 +5,11 @@ name = "autocfg" version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "1.2.1" @@ -25,15 +30,16 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.8.0" +version = "0.8.2" dependencies = [ - "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -58,12 +64,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.65" +version = "0.2.67" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memoffset" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -75,7 +86,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -130,7 +141,7 @@ name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -142,7 +153,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -183,7 +194,7 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -220,14 +231,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" +"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" -"checksum memoffset 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a85c1a8c329f11437034d7313dca647c79096523533a1c79e86f1d0f657c7cc" +"checksum libc 0.2.67 (registry+https://github.com/rust-lang/crates.io-index)" = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018" +"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" @@ -240,7 +253,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" +"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" diff --git a/third_party/rust/crossbeam-epoch/Cargo.toml b/third_party/rust/crossbeam-epoch/Cargo.toml index 0cdcbbbcd02fb0f27903912f2686ffc77c72e24b..7d5c0943b99855497ec34af4ff0f21b2b45955f6 100644 --- a/third_party/rust/crossbeam-epoch/Cargo.toml +++ b/third_party/rust/crossbeam-epoch/Cargo.toml @@ -12,7 +12,7 @@ [package] name = "crossbeam-epoch" -version = "0.8.0" +version = "0.8.2" authors = ["The Crossbeam Project Developers"] description = "Epoch-based garbage collection" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-epoch" @@ -33,6 +33,9 @@ default-features = false version = "1" optional = true +[dependencies.maybe-uninit] +version = "2.0.0" + [dependencies.memoffset] version = "0.5" @@ -42,7 +45,7 @@ default-features = false [dev-dependencies.rand] version = "0.6" [build-dependencies.autocfg] -version = "0.1.6" +version = "1" [features] alloc = ["crossbeam-utils/alloc"] diff --git a/third_party/rust/crossbeam-epoch/src/default.rs b/third_party/rust/crossbeam-epoch/src/default.rs index 734a62428f6a9304858806c37ace6431a0e17142..870e590fa280ee547f70f69fcc5e4d04fe07d406 100644 --- a/third_party/rust/crossbeam-epoch/src/default.rs +++ b/third_party/rust/crossbeam-epoch/src/default.rs @@ -70,6 +70,7 @@ mod tests { super::pin(); // At thread exit, `HANDLE` gets dropped first and `FOO` second. }); - }).unwrap(); + }) + .unwrap(); } } diff --git a/third_party/rust/crossbeam-epoch/src/deferred.rs b/third_party/rust/crossbeam-epoch/src/deferred.rs index 3d22ee633ea34abf1065705bddb4c3f70b2b0815..a0970f1157a038b1605f2a64d5cd57ba7acdec05 100644 --- a/third_party/rust/crossbeam-epoch/src/deferred.rs +++ b/third_party/rust/crossbeam-epoch/src/deferred.rs @@ -4,6 +4,8 @@ use core::marker::PhantomData; use core::mem; use core::ptr; +use maybe_uninit::MaybeUninit; + /// Number of words a piece of `Data` can hold. /// /// Three words should be enough for the majority of cases. For example, you can fit inside it the @@ -36,11 +38,8 @@ impl Deferred { unsafe { if size <= mem::size_of::<Data>() && align <= mem::align_of::<Data>() { - // TODO(taiki-e): when the minimum supported Rust version is bumped to 1.36+, - // replace this with `mem::MaybeUninit`. - #[allow(deprecated)] - let mut data: Data = mem::uninitialized(); - ptr::write(&mut data as *mut Data as *mut F, f); + let mut data = MaybeUninit::<Data>::uninit(); + ptr::write(data.as_mut_ptr() as *mut F, f); unsafe fn call<F: FnOnce()>(raw: *mut u8) { let f: F = ptr::read(raw as *mut F); @@ -49,16 +48,13 @@ impl Deferred { Deferred { call: call::<F>, - data, + data: data.assume_init(), _marker: PhantomData, } } else { let b: Box<F> = Box::new(f); - // TODO(taiki-e): when the minimum supported Rust version is bumped to 1.36+, - // replace this with `mem::MaybeUninit`. - #[allow(deprecated)] - let mut data: Data = mem::uninitialized(); - ptr::write(&mut data as *mut Data as *mut Box<F>, b); + let mut data = MaybeUninit::<Data>::uninit(); + ptr::write(data.as_mut_ptr() as *mut Box<F>, b); unsafe fn call<F: FnOnce()>(raw: *mut u8) { let b: Box<F> = ptr::read(raw as *mut Box<F>); @@ -67,7 +63,7 @@ impl Deferred { Deferred { call: call::<F>, - data, + data: data.assume_init(), _marker: PhantomData, } } diff --git a/third_party/rust/crossbeam-epoch/src/internal.rs b/third_party/rust/crossbeam-epoch/src/internal.rs index 22038f30da2681334244067e8aed811c97b67bca..645511b9c8524cd4a1124af24a902987ed8373e5 100644 --- a/third_party/rust/crossbeam-epoch/src/internal.rs +++ b/third_party/rust/crossbeam-epoch/src/internal.rs @@ -38,13 +38,13 @@ use core::cell::{Cell, UnsafeCell}; use core::mem::{self, ManuallyDrop}; use core::num::Wrapping; -use core::{ptr, fmt}; use core::sync::atomic; use core::sync::atomic::Ordering; +use core::{fmt, ptr}; use crossbeam_utils::CachePadded; -use atomic::{Shared, Owned}; +use atomic::{Owned, Shared}; use collector::{Collector, LocalHandle}; use deferred::Deferred; use epoch::{AtomicEpoch, Epoch}; @@ -62,7 +62,7 @@ const MAX_OBJECTS: usize = 4; pub struct Bag { /// Stashed objects. deferreds: [Deferred; MAX_OBJECTS], - len: usize + len: usize, } /// `Bag::try_push()` requires that it is safe for another thread to execute the given functions. @@ -104,29 +104,91 @@ impl Bag { } impl Default for Bag { + // TODO(taiki-e): when the minimum supported Rust version is bumped to 1.31+, + // replace this with `#[rustfmt::skip]`. + #[cfg_attr(rustfmt, rustfmt_skip)] fn default() -> Self { // TODO: [no_op; MAX_OBJECTS] syntax blocked by https://github.com/rust-lang/rust/issues/49147 #[cfg(not(feature = "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), - 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)] + 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), + 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(feature = "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)] }; + 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), + ], + }; } } @@ -144,7 +206,9 @@ impl Drop for Bag { // can't #[derive(Debug)] because Debug is not implemented for arrays 64 items long impl fmt::Debug for Bag { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Bag").field("deferreds", &&self.deferreds[..self.len]).finish() + f.debug_struct("Bag") + .field("deferreds", &&self.deferreds[..self.len]) + .finish() } } diff --git a/third_party/rust/crossbeam-epoch/src/lib.rs b/third_party/rust/crossbeam-epoch/src/lib.rs index c5b504e50c7162ae14d4eb000eb6acd57764e9b2..282bbe90fea016c80fd1653e59958b2349c7bd2b 100644 --- a/third_party/rust/crossbeam-epoch/src/lib.rs +++ b/third_party/rust/crossbeam-epoch/src/lib.rs @@ -52,7 +52,7 @@ //! [`Collector`]: struct.Collector.html //! [`Shared`]: struct.Shared.html //! [`pin`]: fn.pin.html -//! [`defer`]: fn.defer.html +//! [`defer`]: struct.Guard.html#method.defer #![warn(missing_docs)] #![warn(missing_debug_implementations)] @@ -64,6 +64,8 @@ extern crate cfg_if; #[cfg(feature = "std")] extern crate core; +extern crate maybe_uninit; + cfg_if! { if #[cfg(feature = "alloc")] { extern crate alloc; diff --git a/third_party/rust/crossbeam-epoch/src/sync/list.rs b/third_party/rust/crossbeam-epoch/src/sync/list.rs index 623fbd2a8efb7215d28e5b87ea88acd031f9db5b..8e8899ea2eb500ef16fb4dd34e85eb48ebf7db48 100644 --- a/third_party/rust/crossbeam-epoch/src/sync/list.rs +++ b/third_party/rust/crossbeam-epoch/src/sync/list.rs @@ -243,35 +243,44 @@ impl<'g, T: 'g, C: IsElement<T>> Iterator for Iter<'g, T, C> { // This entry was removed. Try unlinking it from the list. let succ = succ.with_tag(0); - // The tag should never be zero, because removing a node after a logically deleted + // The tag should always be zero, because removing a node after a logically deleted // node leaves the list in an invalid state. debug_assert!(self.curr.tag() == 0); - match self + // Try to unlink `curr` from the list, and get the new value of `self.pred`. + let succ = match self .pred .compare_and_set(self.curr, succ, Acquire, self.guard) { Ok(_) => { - // We succeeded in unlinking this element from the list, so we have to - // schedule deallocation. Deferred drop is okay, because `list.delete()` - // can only be called if `T: 'static`. + // We succeeded in unlinking `curr`, so we have to schedule + // deallocation. Deferred drop is okay, because `list.delete()` can only be + // called if `T: 'static`. unsafe { C::finalize(self.curr.deref(), self.guard); } - // Move over the removed by only advancing `curr`, not `pred`. - self.curr = succ; - continue; + // `succ` is the new value of `self.pred`. + succ } - Err(_) => { - // A concurrent thread modified the predecessor node. Since it might've - // been deleted, we need to restart from `head`. - self.pred = self.head; - self.curr = self.head.load(Acquire, self.guard); - - return Some(Err(IterError::Stalled)); + Err(e) => { + // `e.current` is the current value of `self.pred`. + e.current } + }; + + // If the predecessor node is already marked as deleted, we need to restart from + // `head`. + if succ.tag() != 0 { + self.pred = self.head; + self.curr = self.head.load(Acquire, self.guard); + + return Some(Err(IterError::Stalled)); } + + // Move over the removed by only advancing `curr`, not `pred`. + self.curr = succ; + continue; } // Move one step forward. diff --git a/third_party/rust/crossbeam-epoch/src/sync/queue.rs b/third_party/rust/crossbeam-epoch/src/sync/queue.rs index 6fe0bef37e59b8dd3533f3df41e80682664dea2b..99fb6a1c4f536cc314c42dc435782bec21e924cb 100644 --- a/third_party/rust/crossbeam-epoch/src/sync/queue.rs +++ b/third_party/rust/crossbeam-epoch/src/sync/queue.rs @@ -4,13 +4,16 @@ //! //! Michael and Scott. Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue //! Algorithms. PODC 1996. http://dl.acm.org/citation.cfm?id=248106 +//! +//! Simon Doherty, Lindsay Groves, Victor Luchangco, and Mark Moir. 2004b. Formal Verification of a +//! Practical Lock-Free Queue Algorithm. https://doi.org/10.1007/978-3-540-30232-2_7 -use core::mem::{self, ManuallyDrop}; -use core::ptr; use core::sync::atomic::Ordering::{Acquire, Relaxed, Release}; use crossbeam_utils::CachePadded; +use maybe_uninit::MaybeUninit; + use {unprotected, Atomic, Guard, Owned, Shared}; // The representation here is a singly-linked list, with a sentinel node at the front. In general @@ -22,15 +25,14 @@ pub struct Queue<T> { tail: CachePadded<Atomic<Node<T>>>, } -#[derive(Debug)] struct Node<T> { /// The slot in which a value of type `T` can be stored. /// - /// The type of `data` is `ManuallyDrop<T>` because a `Node<T>` doesn't always contain a `T`. + /// The type of `data` is `MaybeUninit<T>` because a `Node<T>` doesn't always contain a `T`. /// For example, the sentinel node in a queue never contains a value: its slot is always empty. /// Other nodes start their life with a push operation and contain a value until it gets popped /// out. After that such empty nodes get added to the collector for destruction. - data: ManuallyDrop<T>, + data: MaybeUninit<T>, next: Atomic<Node<T>>, } @@ -46,11 +48,8 @@ impl<T> Queue<T> { head: CachePadded::new(Atomic::null()), tail: CachePadded::new(Atomic::null()), }; - // TODO(taiki-e): when the minimum supported Rust version is bumped to 1.36+, - // replace this with `mem::MaybeUninit`. - #[allow(deprecated)] let sentinel = Owned::new(Node { - data: unsafe { mem::uninitialized() }, + data: MaybeUninit::uninit(), next: Atomic::null(), }); unsafe { @@ -90,7 +89,7 @@ impl<T> Queue<T> { /// Adds `t` to the back of the queue, possibly waking up threads blocked on `pop`. pub fn push(&self, t: T, guard: &Guard) { let new = Owned::new(Node { - data: ManuallyDrop::new(t), + data: MaybeUninit::new(t), next: Atomic::null(), }); let new = Owned::into_shared(new, guard); @@ -117,8 +116,14 @@ impl<T> Queue<T> { self.head .compare_and_set(head, next, Release, guard) .map(|_| { + let tail = self.tail.load(Relaxed, guard); + // Advance the tail so that we don't retire a pointer to a reachable node. + if head == tail { + let _ = self.tail.compare_and_set(tail, next, Release, guard); + } guard.defer_destroy(head); - Some(ManuallyDrop::into_inner(ptr::read(&n.data))) + // TODO: Replace with MaybeUninit::read when api is stable + Some(n.data.as_ptr().read()) }) .map_err(|_| ()) }, @@ -138,12 +143,17 @@ impl<T> Queue<T> { let h = unsafe { head.deref() }; let next = h.next.load(Acquire, guard); match unsafe { next.as_ref() } { - Some(n) if condition(&n.data) => unsafe { + Some(n) if condition(unsafe { &*n.data.as_ptr() }) => unsafe { self.head .compare_and_set(head, next, Release, guard) .map(|_| { + let tail = self.tail.load(Relaxed, guard); + // Advance the tail so that we don't retire a pointer to a reachable node. + if head == tail { + let _ = self.tail.compare_and_set(tail, next, Release, guard); + } guard.defer_destroy(head); - Some(ManuallyDrop::into_inner(ptr::read(&n.data))) + Some(n.data.as_ptr().read()) }) .map_err(|_| ()) }, diff --git a/third_party/rust/crossbeam-utils-0.6.5/.cargo-checksum.json b/third_party/rust/crossbeam-utils-0.6.5/.cargo-checksum.json deleted file mode 100644 index ec17be04c27166ca2dbe83cb70a9c2a9667d1fba..0000000000000000000000000000000000000000 --- a/third_party/rust/crossbeam-utils-0.6.5/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"CHANGELOG.md":"e58bfef23e76d04b244941fd4ecdb35837a1a6f1370bf4596cc0280193c9a4f9","Cargo.toml":"2d4d20231a89e61fa6d1d83ad853b274e71d243c992eda5a9de0c9e8ca428ba5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"63ba61fd2e75aa90572476eda5246fc766846af40d31e0bdccbf763d9f0799ba","benches/atomic_cell.rs":"ada69698def9d4eab485a6e0da235aaac001efe49a6b0d6f5c5be381a645310f","src/atomic/atomic_cell.rs":"97a9ec7ac2625ee0a951b984a419fbeab62173ed9c23cab47dfc13ed25e8ee6c","src/atomic/consume.rs":"bfdc7e2d8370a5a3bb1699b6214347c359d66fcc92a2d1345a513676ac91d821","src/atomic/mod.rs":"404eacae422012f3628cb44262df73a5891fe02a17ab345b832e3062982b5a20","src/backoff.rs":"029fede365eaa3408c7359cf868303120903976304aee546aeedcb80085568d5","src/cache_padded.rs":"95b10657b4e50316d2213894e195c61602ff0c6655cc965301de1584fb7d61c7","src/lib.rs":"957df3bd2875147aa1b939fc47f1a8a72719748e9001f27dba2f3589e27a73b4","src/sync/mod.rs":"4c8ad6ec4601f212791b0b531b46ee5decec2f1d14746aa7f2c18e36c609cd8e","src/sync/parker.rs":"55324bbea5b7c6838a0f8467a5b8a5dbd5526c8e1c7fd4f6d64dad1ab19f9be9","src/sync/sharded_lock.rs":"7a401ba621233732c26cf49324748269359d7bc5dc27e0ec26c9493e9a5ec97d","src/sync/wait_group.rs":"21708bbd46daa98e9f788765a9a4ef3b087a8d1e97a6e9406b4a960c95e44ca0","src/thread.rs":"384e3c6e6db565e752169223205991f1eadb1258b1d416758172a40a6c9bd645","tests/atomic_cell.rs":"690f516c7e827b18adec5da1c3249ebb26ff674c5887d863ddc94fe1600b9c28","tests/cache_padded.rs":"02235757a554279dae5053d46314a765059ec036c63a05336353994c2aa344d1","tests/parker.rs":"996212c084286567638919c27d46a250a5d592d8e1a97c1e6a4d7e10c060e4dd","tests/sharded_lock.rs":"1e2e8a355b74d89569873fbba7772235bc64d13a7209ee673f368f4fe6f70c65","tests/thread.rs":"0d86998085a8aace79e5b3dae61aa8bd864492f44aafcce6ec85778954f55809","tests/wait_group.rs":"e3d5168581fb511b760f4249ca487b919cffc60ac2b4610a78db99899772dd5b"},"package":"f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c"} \ No newline at end of file diff --git a/third_party/rust/crossbeam-utils-0.6.5/LICENSE-MIT b/third_party/rust/crossbeam-utils-0.6.5/LICENSE-MIT deleted file mode 100644 index 31aa79387f27e730e33d871925e152e35e428031..0000000000000000000000000000000000000000 --- a/third_party/rust/crossbeam-utils-0.6.5/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/crossbeam-utils-0.6.6/.cargo-checksum.json b/third_party/rust/crossbeam-utils-0.6.6/.cargo-checksum.json new file mode 100644 index 0000000000000000000000000000000000000000..b100cb8e15cf100623b5e47b1863c05a3fb4077d --- /dev/null +++ b/third_party/rust/crossbeam-utils-0.6.6/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"cb975f0361e0cccfe00da4f32d4c87308b20e40f6444d2ef474640fbb15567de","Cargo.toml":"8ad804e9e161a564e57e2cea30349d9658fd3d32bd0b065868073cdcc70a78cb","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"0b293d1b9b129a58f504ff4bc061161ddfaf7c8594e0ca2b526458d4e9acb194","benches/atomic_cell.rs":"fa38d34ddc593bf0999fd65d95ee349c53a11290fbe7bf24870a7e24754ae2ac","src/atomic/atomic_cell.rs":"9f18d8cf7d91750f7646bc2ef7bf5b7444b2c9acdc2e8b6dffd8f0ff696e113b","src/atomic/consume.rs":"bfdc7e2d8370a5a3bb1699b6214347c359d66fcc92a2d1345a513676ac91d821","src/atomic/mod.rs":"404eacae422012f3628cb44262df73a5891fe02a17ab345b832e3062982b5a20","src/backoff.rs":"bc9d2afdd070e0746bc48ff2159bf47b0cfaa68ea09f47eaed18ccc32fc87d67","src/cache_padded.rs":"864f210089eddfd130830f5c700115c2f8b974b71659d7e8ef7bd5e09d7e1f96","src/lib.rs":"3138911610fa97a412c62e4aa5a6cd50524a04f6746c08a5cda8fd1c1d954555","src/sync/mod.rs":"4c8ad6ec4601f212791b0b531b46ee5decec2f1d14746aa7f2c18e36c609cd8e","src/sync/parker.rs":"55324bbea5b7c6838a0f8467a5b8a5dbd5526c8e1c7fd4f6d64dad1ab19f9be9","src/sync/sharded_lock.rs":"7a401ba621233732c26cf49324748269359d7bc5dc27e0ec26c9493e9a5ec97d","src/sync/wait_group.rs":"21708bbd46daa98e9f788765a9a4ef3b087a8d1e97a6e9406b4a960c95e44ca0","src/thread.rs":"ee89256b619c7ed55e04519bb3b9f29e72e6ce1e61e8ba9782a984f5e9fc1bad","tests/atomic_cell.rs":"4423b41f6f23ff2519f4a1f9970436b7fb49968be5bc14dbdbd5ab2d5b1048df","tests/cache_padded.rs":"02235757a554279dae5053d46314a765059ec036c63a05336353994c2aa344d1","tests/parker.rs":"3e5c4e170cebdd9f815f2b31a2b6a01da753fc03e2b1d8e9b899d009f62c6b83","tests/sharded_lock.rs":"3b42218397f1260bed4e0a229f55da83439c0ec9effbbefc86251c9d208979bb","tests/thread.rs":"42baefda11ccd87d9fe1a93bb7d6186b17a86afcf3b9d8f739bc0deefa11ae0f","tests/wait_group.rs":"e3d5168581fb511b760f4249ca487b919cffc60ac2b4610a78db99899772dd5b"},"package":"04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"} \ No newline at end of file diff --git a/third_party/rust/crossbeam-utils-0.6.5/CHANGELOG.md b/third_party/rust/crossbeam-utils-0.6.6/CHANGELOG.md similarity index 88% rename from third_party/rust/crossbeam-utils-0.6.5/CHANGELOG.md rename to third_party/rust/crossbeam-utils-0.6.6/CHANGELOG.md index e3a2bdd0727cd0049ce2e67dcf69a969480011a2..6e2102387c35380e5c395d68c4cd2873e2edae67 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/CHANGELOG.md +++ b/third_party/rust/crossbeam-utils-0.6.6/CHANGELOG.md @@ -1,3 +1,11 @@ +# Version 0.6.6 + +- Add `UnwindSafe` and `RefUnwindSafe` impls for `AtomicCell`. +- Add `AtomicCell::as_ptr()`. +- Add `AtomicCell::take()`. +- Fix a bug in `AtomicCell::compare_exchange()` and `AtomicCell::compare_and_swap()`. +- Various documentation improvements. + # Version 0.6.5 - Rename `Backoff::is_complete()` to `Backoff::is_completed()`. diff --git a/third_party/rust/crossbeam-utils-0.6.5/Cargo.toml b/third_party/rust/crossbeam-utils-0.6.6/Cargo.toml similarity index 92% rename from third_party/rust/crossbeam-utils-0.6.5/Cargo.toml rename to third_party/rust/crossbeam-utils-0.6.6/Cargo.toml index 5c2c84b3cd3698fec2e0fae57bb39a2bc70c8ceb..1dbd675ace46c3395c7ddf4ce60a8e903d300fff 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/Cargo.toml +++ b/third_party/rust/crossbeam-utils-0.6.6/Cargo.toml @@ -3,7 +3,7 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies +# to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're @@ -12,7 +12,7 @@ [package] name = "crossbeam-utils" -version = "0.6.5" +version = "0.6.6" authors = ["The Crossbeam Project Developers"] description = "Utilities for concurrent programming" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils" @@ -23,7 +23,7 @@ categories = ["algorithms", "concurrency", "data-structures", "no-std"] license = "MIT/Apache-2.0" repository = "https://github.com/crossbeam-rs/crossbeam" [dependencies.cfg-if] -version = "0.1" +version = "0.1.2" [dependencies.lazy_static] version = "1.1.0" @@ -32,6 +32,7 @@ optional = true version = "0.6" [features] +alloc = [] default = ["std"] nightly = [] std = ["lazy_static"] diff --git a/third_party/rust/autocfg-0.1.6/LICENSE-APACHE b/third_party/rust/crossbeam-utils-0.6.6/LICENSE-APACHE similarity index 100% rename from third_party/rust/autocfg-0.1.6/LICENSE-APACHE rename to third_party/rust/crossbeam-utils-0.6.6/LICENSE-APACHE diff --git a/third_party/rust/crossbeam-utils-0.7.0/LICENSE-MIT b/third_party/rust/crossbeam-utils-0.6.6/LICENSE-MIT similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/LICENSE-MIT rename to third_party/rust/crossbeam-utils-0.6.6/LICENSE-MIT diff --git a/third_party/rust/crossbeam-utils-0.6.5/README.md b/third_party/rust/crossbeam-utils-0.6.6/README.md similarity index 85% rename from third_party/rust/crossbeam-utils-0.6.5/README.md rename to third_party/rust/crossbeam-utils-0.6.6/README.md index a454c141ed76a88e5ddd6cef05e3c7b6825a4acb..b4a0f6b20fae5d63ea9d2bf53ce1e9f02185d401 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/README.md +++ b/third_party/rust/crossbeam-utils-0.6.6/README.md @@ -10,13 +10,14 @@ https://crates.io/crates/crossbeam-utils) https://docs.rs/crossbeam-utils) []( https://www.rust-lang.org) +[](https://discord.gg/BBYwKq) This crate provides miscellaneous tools for concurrent programming: #### Atomics -* [`AtomicCell`], a thread-safe mutable memory location.<sup>(\*)</sup> -* [`AtomicConsume`], for reading from primitive atomic types with "consume" ordering.<sup>(\*)</sup> +* [`AtomicCell`], a thread-safe mutable memory location.<sup>(no_std)</sup> +* [`AtomicConsume`], for reading from primitive atomic types with "consume" ordering.<sup>(no_std)</sup> #### Thread synchronization @@ -26,11 +27,11 @@ This crate provides miscellaneous tools for concurrent programming: #### Utilities -* [`Backoff`], for exponential backoff in spin loops.<sup>(\*)</sup> -* [`CachePadded`], for padding and aligning a value to the length of a cache line.<sup>(\*)</sup> +* [`Backoff`], for exponential backoff in spin loops.<sup>(no_std)</sup> +* [`CachePadded`], for padding and aligning a value to the length of a cache line.<sup>(no_std)</sup> * [`scope`], for spawning threads that borrow local variables from the stack. -*Features marked with <sup>(\*)</sup> can be used in `no_std` environments.* +*Features marked with <sup>(no_std)</sup> can be used in `no_std` environments.*<br/> [`AtomicCell`]: https://docs.rs/crossbeam-utils/*/crossbeam_utils/atomic/struct.AtomicCell.html [`AtomicConsume`]: https://docs.rs/crossbeam-utils/*/crossbeam_utils/atomic/trait.AtomicConsume.html diff --git a/third_party/rust/crossbeam-utils-0.7.0/benches/atomic_cell.rs b/third_party/rust/crossbeam-utils-0.6.6/benches/atomic_cell.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/benches/atomic_cell.rs rename to third_party/rust/crossbeam-utils-0.6.6/benches/atomic_cell.rs diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/atomic/atomic_cell.rs b/third_party/rust/crossbeam-utils-0.6.6/src/atomic/atomic_cell.rs similarity index 86% rename from third_party/rust/crossbeam-utils-0.6.5/src/atomic/atomic_cell.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/atomic/atomic_cell.rs index 31ad7d354ec5a11f91856484a0f9c603b18f3804..f3118ecacf0ed63d0a511225301647455d8980d4 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/src/atomic/atomic_cell.rs +++ b/third_party/rust/crossbeam-utils-0.6.6/src/atomic/atomic_cell.rs @@ -2,9 +2,11 @@ use core::cell::UnsafeCell; use core::fmt; use core::mem; use core::ptr; -use core::slice; use core::sync::atomic::{self, AtomicBool, AtomicUsize, Ordering}; +#[cfg(feature = "std")] +use std::panic::{RefUnwindSafe, UnwindSafe}; + use Backoff; /// A thread-safe mutable memory location. @@ -15,9 +17,15 @@ use Backoff; /// global locks otherwise. You can call [`AtomicCell::<T>::is_lock_free()`] to check whether /// atomic instructions or locks will be used. /// +/// Atomic loads use the [`Acquire`] ordering and atomic stores use the [`Release`] ordering. +/// /// [`Cell`]: https://doc.rust-lang.org/std/cell/struct.Cell.html /// [`AtomicCell::<T>::is_lock_free()`]: struct.AtomicCell.html#method.is_lock_free -pub struct AtomicCell<T> { +/// [`Acquire`]: https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html#variant.Acquire +/// [`Release`]: https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html#variant.Release +// TODO(@jeehoonkang): when the minimum supported Rust version is bumped to 1.28+, apply the +// attribute `#[repr(transparent)]`. +pub struct AtomicCell<T: ?Sized> { /// The inner value. /// /// If this value can be transmuted into a primitive atomic type, it will be treated as such. @@ -29,6 +37,11 @@ pub struct AtomicCell<T> { unsafe impl<T: Send> Send for AtomicCell<T> {} unsafe impl<T: Send> Sync for AtomicCell<T> {} +#[cfg(feature = "std")] +impl<T> UnwindSafe for AtomicCell<T> {} +#[cfg(feature = "std")] +impl<T> RefUnwindSafe for AtomicCell<T> {} + impl<T> AtomicCell<T> { /// Creates a new atomic cell initialized with `val`. /// @@ -45,22 +58,6 @@ impl<T> AtomicCell<T> { } } - /// Returns a mutable reference to the inner value. - /// - /// # Examples - /// - /// ``` - /// use crossbeam_utils::atomic::AtomicCell; - /// - /// let mut a = AtomicCell::new(7); - /// *a.get_mut() += 1; - /// - /// assert_eq!(a.load(), 8); - /// ``` - pub fn get_mut(&mut self) -> &mut T { - unsafe { &mut *self.value.get() } - } - /// Unwraps the atomic cell and returns its inner value. /// /// # Examples @@ -150,6 +147,61 @@ impl<T> AtomicCell<T> { } } +impl<T: ?Sized> AtomicCell<T> { + /// Returns a raw pointer to the underlying data in this atomic cell. + /// + /// # Examples + /// + /// ``` + /// use crossbeam_utils::atomic::AtomicCell; + /// + /// let mut a = AtomicCell::new(5); + /// + /// let ptr = a.as_ptr(); + /// ``` + #[inline] + pub fn as_ptr(&self) -> *mut T { + self.value.get() + } + + /// Returns a mutable reference to the inner value. + /// + /// # Examples + /// + /// ``` + /// use crossbeam_utils::atomic::AtomicCell; + /// + /// let mut a = AtomicCell::new(7); + /// *a.get_mut() += 1; + /// + /// assert_eq!(a.load(), 8); + /// ``` + #[doc(hidden)] + #[deprecated(note = "this method is unsound and will be removed in the next release")] + pub fn get_mut(&mut self) -> &mut T { + unsafe { &mut *self.value.get() } + } +} + +impl<T: Default> AtomicCell<T> { + /// Takes the value of the atomic cell, leaving `Default::default()` in its place. + /// + /// # Examples + /// + /// ``` + /// use crossbeam_utils::atomic::AtomicCell; + /// + /// let a = AtomicCell::new(5); + /// let five = a.take(); + /// + /// assert_eq!(five, 5); + /// assert_eq!(a.into_inner(), 0); + /// ``` + pub fn take(&self) -> T { + self.swap(Default::default()) + } +} + impl<T: Copy> AtomicCell<T> { /// Loads a value. /// @@ -180,10 +232,10 @@ impl<T: Copy + Eq> AtomicCell<T> { /// /// let a = AtomicCell::new(1); /// - /// assert_eq!(a.compare_exchange(2, 3), Err(1)); + /// assert_eq!(a.compare_and_swap(2, 3), 1); /// assert_eq!(a.load(), 1); /// - /// assert_eq!(a.compare_exchange(1, 2), Ok(1)); + /// assert_eq!(a.compare_and_swap(1, 2), 1); /// assert_eq!(a.load(), 2); /// ``` pub fn compare_and_swap(&self, current: T, new: T) -> T { @@ -211,23 +263,8 @@ impl<T: Copy + Eq> AtomicCell<T> { /// assert_eq!(a.compare_exchange(1, 2), Ok(1)); /// assert_eq!(a.load(), 2); /// ``` - pub fn compare_exchange(&self, mut current: T, new: T) -> Result<T, T> { - loop { - match unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) } { - Ok(_) => return Ok(current), - Err(previous) => { - if previous != current { - return Err(previous); - } - - // The compare-exchange operation has failed and didn't store `new`. The - // failure is either spurious, or `previous` was semantically equal to - // `current` but not byte-equal. Let's retry with `previous` as the new - // `current`. - current = previous; - } - } - } + pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> { + unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) } } } @@ -252,7 +289,7 @@ macro_rules! impl_arithmetic { pub fn fetch_add(&self, val: $t) -> $t { if can_transmute::<$t, atomic::AtomicUsize>() { let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) }; - a.fetch_add(val as usize, Ordering::SeqCst) as $t + a.fetch_add(val as usize, Ordering::AcqRel) as $t } else { let _guard = lock(self.value.get() as usize).write(); let value = unsafe { &mut *(self.value.get()) }; @@ -280,7 +317,7 @@ macro_rules! impl_arithmetic { pub fn fetch_sub(&self, val: $t) -> $t { if can_transmute::<$t, atomic::AtomicUsize>() { let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) }; - a.fetch_sub(val as usize, Ordering::SeqCst) as $t + a.fetch_sub(val as usize, Ordering::AcqRel) as $t } else { let _guard = lock(self.value.get() as usize).write(); let value = unsafe { &mut *(self.value.get()) }; @@ -306,7 +343,7 @@ macro_rules! impl_arithmetic { pub fn fetch_and(&self, val: $t) -> $t { if can_transmute::<$t, atomic::AtomicUsize>() { let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) }; - a.fetch_and(val as usize, Ordering::SeqCst) as $t + a.fetch_and(val as usize, Ordering::AcqRel) as $t } else { let _guard = lock(self.value.get() as usize).write(); let value = unsafe { &mut *(self.value.get()) }; @@ -332,7 +369,7 @@ macro_rules! impl_arithmetic { pub fn fetch_or(&self, val: $t) -> $t { if can_transmute::<$t, atomic::AtomicUsize>() { let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) }; - a.fetch_or(val as usize, Ordering::SeqCst) as $t + a.fetch_or(val as usize, Ordering::AcqRel) as $t } else { let _guard = lock(self.value.get() as usize).write(); let value = unsafe { &mut *(self.value.get()) }; @@ -358,7 +395,7 @@ macro_rules! impl_arithmetic { pub fn fetch_xor(&self, val: $t) -> $t { if can_transmute::<$t, atomic::AtomicUsize>() { let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) }; - a.fetch_xor(val as usize, Ordering::SeqCst) as $t + a.fetch_xor(val as usize, Ordering::AcqRel) as $t } else { let _guard = lock(self.value.get() as usize).write(); let value = unsafe { &mut *(self.value.get()) }; @@ -388,7 +425,7 @@ macro_rules! impl_arithmetic { #[inline] pub fn fetch_add(&self, val: $t) -> $t { let a = unsafe { &*(self.value.get() as *const $atomic) }; - a.fetch_add(val, Ordering::SeqCst) + a.fetch_add(val, Ordering::AcqRel) } /// Decrements the current value by `val` and returns the previous value. @@ -408,7 +445,7 @@ macro_rules! impl_arithmetic { #[inline] pub fn fetch_sub(&self, val: $t) -> $t { let a = unsafe { &*(self.value.get() as *const $atomic) }; - a.fetch_sub(val, Ordering::SeqCst) + a.fetch_sub(val, Ordering::AcqRel) } /// Applies bitwise "and" to the current value and returns the previous value. @@ -426,7 +463,7 @@ macro_rules! impl_arithmetic { #[inline] pub fn fetch_and(&self, val: $t) -> $t { let a = unsafe { &*(self.value.get() as *const $atomic) }; - a.fetch_and(val, Ordering::SeqCst) + a.fetch_and(val, Ordering::AcqRel) } /// Applies bitwise "or" to the current value and returns the previous value. @@ -444,7 +481,7 @@ macro_rules! impl_arithmetic { #[inline] pub fn fetch_or(&self, val: $t) -> $t { let a = unsafe { &*(self.value.get() as *const $atomic) }; - a.fetch_or(val, Ordering::SeqCst) + a.fetch_or(val, Ordering::AcqRel) } /// Applies bitwise "xor" to the current value and returns the previous value. @@ -462,7 +499,7 @@ macro_rules! impl_arithmetic { #[inline] pub fn fetch_xor(&self, val: $t) -> $t { let a = unsafe { &*(self.value.get() as *const $atomic) }; - a.fetch_xor(val, Ordering::SeqCst) + a.fetch_xor(val, Ordering::AcqRel) } } }; @@ -528,7 +565,7 @@ impl AtomicCell<bool> { #[inline] pub fn fetch_and(&self, val: bool) -> bool { let a = unsafe { &*(self.value.get() as *const AtomicBool) }; - a.fetch_and(val, Ordering::SeqCst) + a.fetch_and(val, Ordering::AcqRel) } /// Applies logical "or" to the current value and returns the previous value. @@ -549,7 +586,7 @@ impl AtomicCell<bool> { #[inline] pub fn fetch_or(&self, val: bool) -> bool { let a = unsafe { &*(self.value.get() as *const AtomicBool) }; - a.fetch_or(val, Ordering::SeqCst) + a.fetch_or(val, Ordering::AcqRel) } /// Applies logical "xor" to the current value and returns the previous value. @@ -570,7 +607,7 @@ impl AtomicCell<bool> { #[inline] pub fn fetch_xor(&self, val: bool) -> bool { let a = unsafe { &*(self.value.get() as *const AtomicBool) }; - a.fetch_xor(val, Ordering::SeqCst) + a.fetch_xor(val, Ordering::AcqRel) } } @@ -588,15 +625,6 @@ impl<T: Copy + fmt::Debug> fmt::Debug for AtomicCell<T> { } } -/// Returns `true` if the two values are equal byte-for-byte. -fn byte_eq<T>(a: &T, b: &T) -> bool { - unsafe { - let a = slice::from_raw_parts(a as *const _ as *const u8, mem::size_of::<T>()); - let b = slice::from_raw_parts(b as *const _ as *const u8, mem::size_of::<T>()); - a == b - } -} - /// Returns `true` if values of type `A` can be transmuted into values of type `B`. fn can_transmute<A, B>() -> bool { // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`. @@ -803,7 +831,7 @@ fn atomic_is_lock_free<T>() -> bool { /// Atomically reads data from `src`. /// -/// This operation uses the `SeqCst` ordering. If possible, an atomic instructions is used, and a +/// This operation uses the `Acquire` ordering. If possible, an atomic instructions is used, and a /// global lock otherwise. unsafe fn atomic_load<T>(src: *mut T) -> T where @@ -813,7 +841,7 @@ where T, a, { a = &*(src as *const _ as *const _); - mem::transmute_copy(&a.load(Ordering::SeqCst)) + mem::transmute_copy(&a.load(Ordering::Acquire)) }, { let lock = lock(src as usize); @@ -844,34 +872,33 @@ where /// Atomically writes `val` to `dst`. /// -/// This operation uses the `SeqCst` ordering. If possible, an atomic instructions is used, and a +/// This operation uses the `Release` ordering. If possible, an atomic instructions is used, and a /// global lock otherwise. unsafe fn atomic_store<T>(dst: *mut T, val: T) { atomic! { T, a, { a = &*(dst as *const _ as *const _); - let res = a.store(mem::transmute_copy(&val), Ordering::SeqCst); + a.store(mem::transmute_copy(&val), Ordering::Release); mem::forget(val); - res }, { let _guard = lock(dst as usize).write(); - ptr::write(dst, val) + ptr::write(dst, val); } } } /// Atomically swaps data at `dst` with `val`. /// -/// This operation uses the `SeqCst` ordering. If possible, an atomic instructions is used, and a +/// This operation uses the `AcqRel` ordering. If possible, an atomic instructions is used, and a /// global lock otherwise. unsafe fn atomic_swap<T>(dst: *mut T, val: T) -> T { atomic! { T, a, { a = &*(dst as *const _ as *const _); - let res = mem::transmute_copy(&a.swap(mem::transmute_copy(&val), Ordering::SeqCst)); + let res = mem::transmute_copy(&a.swap(mem::transmute_copy(&val), Ordering::AcqRel)); mem::forget(val); res }, @@ -887,31 +914,48 @@ unsafe fn atomic_swap<T>(dst: *mut T, val: T) -> T { /// /// Returns the old value on success, or the current value at `dst` on failure. /// -/// This operation uses the `SeqCst` ordering. If possible, an atomic instructions is used, and a +/// This operation uses the `AcqRel` ordering. If possible, an atomic instructions is used, and a /// global lock otherwise. -unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T, current: T, new: T) -> Result<T, T> +unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T, mut current: T, new: T) -> Result<T, T> where - T: Copy, + T: Copy + Eq, { atomic! { T, a, { a = &*(dst as *const _ as *const _); - let res = a.compare_exchange_weak( - mem::transmute_copy(¤t), - mem::transmute_copy(&new), - Ordering::SeqCst, - Ordering::SeqCst, - ); - match res { - Ok(v) => Ok(mem::transmute_copy(&v)), - Err(v) => Err(mem::transmute_copy(&v)), + let mut current_raw = mem::transmute_copy(¤t); + let new_raw = mem::transmute_copy(&new); + + loop { + match a.compare_exchange_weak( + current_raw, + new_raw, + Ordering::AcqRel, + Ordering::Acquire, + ) { + Ok(_) => break Ok(current), + Err(previous_raw) => { + let previous = mem::transmute_copy(&previous_raw); + + if !T::eq(&previous, ¤t) { + break Err(previous); + } + + // The compare-exchange operation has failed and didn't store `new`. The + // failure is either spurious, or `previous` was semantically equal to + // `current` but not byte-equal. Let's retry with `previous` as the new + // `current`. + current = previous; + current_raw = previous_raw; + } + } } }, { let guard = lock(dst as usize).write(); - if byte_eq(&*dst, ¤t) { + if T::eq(&*dst, ¤t) { Ok(ptr::replace(dst, new)) } else { let val = ptr::read(dst); diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/atomic/consume.rs b/third_party/rust/crossbeam-utils-0.6.6/src/atomic/consume.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.6.5/src/atomic/consume.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/atomic/consume.rs diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/atomic/mod.rs b/third_party/rust/crossbeam-utils-0.6.6/src/atomic/mod.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.6.5/src/atomic/mod.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/atomic/mod.rs diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/backoff.rs b/third_party/rust/crossbeam-utils-0.6.6/src/backoff.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/src/backoff.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/backoff.rs diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/cache_padded.rs b/third_party/rust/crossbeam-utils-0.6.6/src/cache_padded.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/src/cache_padded.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/cache_padded.rs diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/lib.rs b/third_party/rust/crossbeam-utils-0.6.6/src/lib.rs similarity index 88% rename from third_party/rust/crossbeam-utils-0.6.5/src/lib.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/lib.rs index 82b49aa5bf2e50852a4d2f1f92179d509dafdd6d..4df2ac8a455c83eeab11c2ce2fca902fbd3bbaff 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/src/lib.rs +++ b/third_party/rust/crossbeam-utils-0.6.6/src/lib.rs @@ -29,7 +29,6 @@ #![warn(missing_docs)] #![warn(missing_debug_implementations)] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(alloc))] #![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))] #[macro_use] @@ -38,16 +37,17 @@ extern crate cfg_if; extern crate core; cfg_if! { - if #[cfg(feature = "nightly")] { + if #[cfg(feature = "alloc")] { extern crate alloc; - } else { - mod alloc { - extern crate std; - pub use self::std::*; - } + } else if #[cfg(feature = "std")] { + extern crate std as alloc; } } +#[cfg_attr( + feature = "nightly", + cfg(all(target_has_atomic = "cas", target_has_atomic = "ptr")) +)] pub mod atomic; mod cache_padded; diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/sync/mod.rs b/third_party/rust/crossbeam-utils-0.6.6/src/sync/mod.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.6.5/src/sync/mod.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/sync/mod.rs diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/sync/parker.rs b/third_party/rust/crossbeam-utils-0.6.6/src/sync/parker.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.6.5/src/sync/parker.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/sync/parker.rs diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/sync/sharded_lock.rs b/third_party/rust/crossbeam-utils-0.6.6/src/sync/sharded_lock.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.6.5/src/sync/sharded_lock.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/sync/sharded_lock.rs diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/sync/wait_group.rs b/third_party/rust/crossbeam-utils-0.6.6/src/sync/wait_group.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.6.5/src/sync/wait_group.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/sync/wait_group.rs diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/thread.rs b/third_party/rust/crossbeam-utils-0.6.6/src/thread.rs similarity index 99% rename from third_party/rust/crossbeam-utils-0.6.5/src/thread.rs rename to third_party/rust/crossbeam-utils-0.6.6/src/thread.rs index 495e9b1ca8130d221251ccd6bd19a72fcfd07308..2613fb7855a9c358eecb18e657986c500347e430 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/src/thread.rs +++ b/third_party/rust/crossbeam-utils-0.6.6/src/thread.rs @@ -74,7 +74,7 @@ //! `'static` lifetime because the borrow checker cannot be sure when the thread will complete. //! //! A scope creates a clear boundary between variables outside the scope and threads inside the -//! scope. Whenever a s.spawns a thread, it promises to join the thread before the scope ends. +//! scope. Whenever a scope spawns a thread, it promises to join the thread before the scope ends. //! This way we guarantee to the borrow checker that scoped threads only live within the scope and //! can safely access variables outside it. //! @@ -92,14 +92,14 @@ //! // Not going to compile because we're trying to borrow `s`, //! // which lives *inside* the scope! :( //! s.spawn(|_| println!("nested thread")); -//! }}); +//! }); //! }); //! ``` //! //! Fortunately, there is a solution. Every scoped thread is passed a reference to its scope as an //! argument, which can be used for spawning nested threads: //! -//! ```ignore +//! ``` //! use crossbeam_utils::thread; //! //! thread::scope(|s| { @@ -107,7 +107,7 @@ //! s.spawn(|s| { //! // Yay, this works because we're using a fresh argument `s`! :) //! s.spawn(|_| println!("nested thread")); -//! }}); +//! }); //! }); //! ``` //! diff --git a/third_party/rust/crossbeam-utils-0.7.0/tests/atomic_cell.rs b/third_party/rust/crossbeam-utils-0.6.6/tests/atomic_cell.rs similarity index 96% rename from third_party/rust/crossbeam-utils-0.7.0/tests/atomic_cell.rs rename to third_party/rust/crossbeam-utils-0.6.6/tests/atomic_cell.rs index 57206aeda1edb7bbfedaa8425c4d08a3bf5f84e7..940619233340d775fcd4e17b1fee328bd991f029 100644 --- a/third_party/rust/crossbeam-utils-0.7.0/tests/atomic_cell.rs +++ b/third_party/rust/crossbeam-utils-0.6.6/tests/atomic_cell.rs @@ -223,12 +223,3 @@ fn garbage_padding() { assert!(cell.compare_exchange(prev, next).is_ok()); println!(); } - -#[cfg(has_min_const_fn)] -#[test] -fn const_atomic_cell_new() { - static CELL: AtomicCell<usize> = AtomicCell::new(0); - - CELL.store(1); - assert_eq!(CELL.load(), 1); -} diff --git a/third_party/rust/crossbeam-utils-0.6.5/tests/cache_padded.rs b/third_party/rust/crossbeam-utils-0.6.6/tests/cache_padded.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.6.5/tests/cache_padded.rs rename to third_party/rust/crossbeam-utils-0.6.6/tests/cache_padded.rs diff --git a/third_party/rust/crossbeam-utils-0.7.0/tests/parker.rs b/third_party/rust/crossbeam-utils-0.6.6/tests/parker.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/tests/parker.rs rename to third_party/rust/crossbeam-utils-0.6.6/tests/parker.rs diff --git a/third_party/rust/crossbeam-utils-0.7.0/tests/sharded_lock.rs b/third_party/rust/crossbeam-utils-0.6.6/tests/sharded_lock.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/tests/sharded_lock.rs rename to third_party/rust/crossbeam-utils-0.6.6/tests/sharded_lock.rs diff --git a/third_party/rust/crossbeam-utils-0.6.5/tests/thread.rs b/third_party/rust/crossbeam-utils-0.6.6/tests/thread.rs similarity index 96% rename from third_party/rust/crossbeam-utils-0.6.5/tests/thread.rs rename to third_party/rust/crossbeam-utils-0.6.6/tests/thread.rs index ac7c2b2a78db04a42fe87da5b412caacf7cddc4d..b691745e0b85ef63fa2bac7449f49bc045cb5180 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/tests/thread.rs +++ b/third_party/rust/crossbeam-utils-0.6.6/tests/thread.rs @@ -23,7 +23,8 @@ fn join() { panic!("\"My honey is running out!\", said Pooh."); }); assert!(panic_handle.join().is_err()); - }).unwrap(); + }) + .unwrap(); // There should be sufficient synchronization. assert_eq!(1, counter.load(Ordering::Relaxed)); @@ -38,7 +39,8 @@ fn counter() { counter.fetch_add(1, Ordering::Relaxed); }); } - }).unwrap(); + }) + .unwrap(); assert_eq!(THREADS, counter.load(Ordering::Relaxed)); } @@ -54,9 +56,11 @@ fn counter_builder() { .stack_size(SMALL_STACK_SIZE) .spawn(|_| { counter.fetch_add(1, Ordering::Relaxed); - }).unwrap(); + }) + .unwrap(); } - }).unwrap(); + }) + .unwrap(); assert_eq!(THREADS, counter.load(Ordering::Relaxed)); } @@ -157,7 +161,8 @@ fn nesting() { wrapper.recurse(scope, 5); }); }); - }).unwrap(); + }) + .unwrap(); } #[test] @@ -171,5 +176,6 @@ fn join_nested() { }); sleep(Duration::from_millis(100)); - }).unwrap(); + }) + .unwrap(); } diff --git a/third_party/rust/crossbeam-utils-0.6.5/tests/wait_group.rs b/third_party/rust/crossbeam-utils-0.6.6/tests/wait_group.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.6.5/tests/wait_group.rs rename to third_party/rust/crossbeam-utils-0.6.6/tests/wait_group.rs diff --git a/third_party/rust/crossbeam-utils-0.7.0/LICENSE-APACHE b/third_party/rust/crossbeam-utils-0.7.0/LICENSE-APACHE deleted file mode 100644 index 16fe87b06e802f094b3fbb0894b137bca2b16ef1..0000000000000000000000000000000000000000 --- a/third_party/rust/crossbeam-utils-0.7.0/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/third_party/rust/crossbeam-utils-0.7.0/build.rs b/third_party/rust/crossbeam-utils-0.7.0/build.rs deleted file mode 100644 index d451c24b2f1fa64f283c026693f838f7aabbc7e3..0000000000000000000000000000000000000000 --- a/third_party/rust/crossbeam-utils-0.7.0/build.rs +++ /dev/null @@ -1,8 +0,0 @@ -extern crate autocfg; - -fn main() { - let cfg = autocfg::new(); - if cfg.probe_rustc_version(1, 31) { - println!("cargo:rustc-cfg=has_min_const_fn"); - } -} diff --git a/third_party/rust/crossbeam-utils-0.7.0/.cargo-checksum.json b/third_party/rust/crossbeam-utils-0.7.2/.cargo-checksum.json similarity index 51% rename from third_party/rust/crossbeam-utils-0.7.0/.cargo-checksum.json rename to third_party/rust/crossbeam-utils-0.7.2/.cargo-checksum.json index 330718f051e462b76313a7b66ce93f761515592a..47f9d2b5e748cc4574e5761d19681ebb1c4d74d3 100644 --- a/third_party/rust/crossbeam-utils-0.7.0/.cargo-checksum.json +++ b/third_party/rust/crossbeam-utils-0.7.2/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"c728a651e916eeb36060274c25cf28817920caf498eb5a367fecdaebe3139f5b","Cargo.toml":"d72c5990059398ec7a203d13a4fc8c5dd7e1c051199415d33475675acb377f9a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"9010e511423b1159a33c84433d9e6cb8df1d08938e4d6cc8656bcec9bdde0eb8","benches/atomic_cell.rs":"fa38d34ddc593bf0999fd65d95ee349c53a11290fbe7bf24870a7e24754ae2ac","build.rs":"825c47ae19028dc4b28101ec71c04e7e41b8b185f6ecbeacee223596524c86ad","src/atomic/atomic_cell.rs":"609adf6aa30d8685c1f708887a17c19f90f8751400b83d8146d078afb5a31c48","src/atomic/consume.rs":"bfdc7e2d8370a5a3bb1699b6214347c359d66fcc92a2d1345a513676ac91d821","src/atomic/mod.rs":"6c3efec60aee6a2e68dfa6fe3c059beab8429c150459ce5cfc736e8b5f95301e","src/atomic/seq_lock.rs":"4797f76beb0ec3eb363c2d49e9548adc8d042867b1602c1b8ca6269463d84e82","src/atomic/seq_lock_wide.rs":"d27243fae36ae9ff72cbf24defcac4abb2aef3fa11a47f352702708a1eee6a06","src/backoff.rs":"bc9d2afdd070e0746bc48ff2159bf47b0cfaa68ea09f47eaed18ccc32fc87d67","src/cache_padded.rs":"864f210089eddfd130830f5c700115c2f8b974b71659d7e8ef7bd5e09d7e1f96","src/lib.rs":"63096ede0c6ccdee05e910c2cce41da6df283868b658f9aa18c8fba8ac0f901d","src/sync/mod.rs":"4c8ad6ec4601f212791b0b531b46ee5decec2f1d14746aa7f2c18e36c609cd8e","src/sync/parker.rs":"55324bbea5b7c6838a0f8467a5b8a5dbd5526c8e1c7fd4f6d64dad1ab19f9be9","src/sync/sharded_lock.rs":"7a401ba621233732c26cf49324748269359d7bc5dc27e0ec26c9493e9a5ec97d","src/sync/wait_group.rs":"21708bbd46daa98e9f788765a9a4ef3b087a8d1e97a6e9406b4a960c95e44ca0","src/thread.rs":"81f6ee718c5251083024583d351a1713cb6a850c284f68e5fa8a35d2ed4b33ba","tests/atomic_cell.rs":"a3c9e7d5832c92fa7e39710a3dc84b4a906eb93479386fba75ff851dd1c908ae","tests/cache_padded.rs":"02235757a554279dae5053d46314a765059ec036c63a05336353994c2aa344d1","tests/parker.rs":"3e5c4e170cebdd9f815f2b31a2b6a01da753fc03e2b1d8e9b899d009f62c6b83","tests/sharded_lock.rs":"3b42218397f1260bed4e0a229f55da83439c0ec9effbbefc86251c9d208979bb","tests/thread.rs":"4be7b293b5f13d7a158a231ba7f7b086bd8fe19aaf11b1c9a8a6cdf7bba6fdfc","tests/wait_group.rs":"e3d5168581fb511b760f4249ca487b919cffc60ac2b4610a78db99899772dd5b"},"package":"ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"} \ No newline at end of file +{"files":{"CHANGELOG.md":"ed7fb11c83cc30f6e7af6a42cae2cb087276ba1668da98268c86fccf9069baa7","Cargo.toml":"3c1187fa9a66336c9c959c87c6ad499f6a6adabb6a10506abaf6ed53e02d57cb","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"9010e511423b1159a33c84433d9e6cb8df1d08938e4d6cc8656bcec9bdde0eb8","benches/atomic_cell.rs":"fa38d34ddc593bf0999fd65d95ee349c53a11290fbe7bf24870a7e24754ae2ac","build.rs":"1ceb20e3c4e089a4dbf326df7924643be0bd6d50512b0b0a0729dbb30522eba8","src/atomic/atomic_cell.rs":"49b8a014e7009292c1eb3b241c2120a661bffcc40bf7b9de83dbb6928b5315b4","src/atomic/consume.rs":"bfdc7e2d8370a5a3bb1699b6214347c359d66fcc92a2d1345a513676ac91d821","src/atomic/mod.rs":"6c3efec60aee6a2e68dfa6fe3c059beab8429c150459ce5cfc736e8b5f95301e","src/atomic/seq_lock.rs":"4797f76beb0ec3eb363c2d49e9548adc8d042867b1602c1b8ca6269463d84e82","src/atomic/seq_lock_wide.rs":"4b2eb90599fbf548e79b8da5e2533d6f7c133245ae8dd48353ef52b1d2aa17f0","src/backoff.rs":"bc9d2afdd070e0746bc48ff2159bf47b0cfaa68ea09f47eaed18ccc32fc87d67","src/cache_padded.rs":"864f210089eddfd130830f5c700115c2f8b974b71659d7e8ef7bd5e09d7e1f96","src/lib.rs":"63096ede0c6ccdee05e910c2cce41da6df283868b658f9aa18c8fba8ac0f901d","src/sync/mod.rs":"02a7cc2a5ebb988a86aeebf7a40752f595e5eb494750e63cdbefd71c4643e2a3","src/sync/parker.rs":"442d8814339fdd9d7074e7e00695c64e6bbb62a2b0c1c8c1e0f4a471c25ccbbd","src/sync/sharded_lock.rs":"756a27476cbbdb03629a18d5b82c6153f7f168d8ef28f0fa17daf103affcc013","src/sync/wait_group.rs":"319611cfba289e272d38bdc9624ce110e37db5ffa2644d23dc330edc153850f0","src/thread.rs":"81f6ee718c5251083024583d351a1713cb6a850c284f68e5fa8a35d2ed4b33ba","tests/atomic_cell.rs":"945885f96d6a5971d6bfbd27ec8da79d337558373a631ffe2c83c6851da360e7","tests/cache_padded.rs":"02235757a554279dae5053d46314a765059ec036c63a05336353994c2aa344d1","tests/parker.rs":"3e5c4e170cebdd9f815f2b31a2b6a01da753fc03e2b1d8e9b899d009f62c6b83","tests/sharded_lock.rs":"3b42218397f1260bed4e0a229f55da83439c0ec9effbbefc86251c9d208979bb","tests/thread.rs":"4be7b293b5f13d7a158a231ba7f7b086bd8fe19aaf11b1c9a8a6cdf7bba6fdfc","tests/wait_group.rs":"e3d5168581fb511b760f4249ca487b919cffc60ac2b4610a78db99899772dd5b"},"package":"c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"} \ No newline at end of file diff --git a/third_party/rust/crossbeam-utils-0.7.0/CHANGELOG.md b/third_party/rust/crossbeam-utils-0.7.2/CHANGELOG.md similarity index 92% rename from third_party/rust/crossbeam-utils-0.7.0/CHANGELOG.md rename to third_party/rust/crossbeam-utils-0.7.2/CHANGELOG.md index 160e92888157d981f855e6f12fafbd3b7d9d9a64..d5fee12d1f70ea82b8f4ec56bd62b84366263f8c 100644 --- a/third_party/rust/crossbeam-utils-0.7.0/CHANGELOG.md +++ b/third_party/rust/crossbeam-utils-0.7.2/CHANGELOG.md @@ -1,3 +1,12 @@ +# Version 0.7.2 + +- Fix bug in release (yanking 0.7.1) + +# Version 0.7.1 + +- Bump `autocfg` dependency to version 1.0. (#460) +- Make `AtomicCell` lockfree for u8, u16, u32, u64 sized values at 1.34+. (#454) + # Version 0.7.0 - Bump the minimum required version to 1.28. diff --git a/third_party/rust/crossbeam-utils-0.7.0/Cargo.toml b/third_party/rust/crossbeam-utils-0.7.2/Cargo.toml similarity index 97% rename from third_party/rust/crossbeam-utils-0.7.0/Cargo.toml rename to third_party/rust/crossbeam-utils-0.7.2/Cargo.toml index c16268bf6ec0609b0da1d4bb0a52bc4e1eaf6ba6..372e06fd0bd7a3ed73c81795340055dc3cc65105 100644 --- a/third_party/rust/crossbeam-utils-0.7.0/Cargo.toml +++ b/third_party/rust/crossbeam-utils-0.7.2/Cargo.toml @@ -12,7 +12,7 @@ [package] name = "crossbeam-utils" -version = "0.7.0" +version = "0.7.2" authors = ["The Crossbeam Project Developers"] description = "Utilities for concurrent programming" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils" @@ -31,7 +31,7 @@ optional = true [dev-dependencies.rand] version = "0.6" [build-dependencies.autocfg] -version = "0.1.6" +version = "1" [features] alloc = [] diff --git a/third_party/rust/crossbeam-utils-0.6.5/LICENSE-APACHE b/third_party/rust/crossbeam-utils-0.7.2/LICENSE-APACHE similarity index 100% rename from third_party/rust/crossbeam-utils-0.6.5/LICENSE-APACHE rename to third_party/rust/crossbeam-utils-0.7.2/LICENSE-APACHE diff --git a/third_party/rust/autocfg-0.1.6/LICENSE-MIT b/third_party/rust/crossbeam-utils-0.7.2/LICENSE-MIT similarity index 93% rename from third_party/rust/autocfg-0.1.6/LICENSE-MIT rename to third_party/rust/crossbeam-utils-0.7.2/LICENSE-MIT index 44fbc4d8b90dbe07864fdf49939308839e5735b2..068d491fd551ae2531f4d28583245719a2e19e2d 100644 --- a/third_party/rust/autocfg-0.1.6/LICENSE-MIT +++ b/third_party/rust/crossbeam-utils-0.7.2/LICENSE-MIT @@ -1,4 +1,6 @@ -Copyright (c) 2018 Josh Stone +The MIT License (MIT) + +Copyright (c) 2019 The Crossbeam Project Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated diff --git a/third_party/rust/crossbeam-utils-0.7.0/README.md b/third_party/rust/crossbeam-utils-0.7.2/README.md similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/README.md rename to third_party/rust/crossbeam-utils-0.7.2/README.md diff --git a/third_party/rust/crossbeam-utils-0.6.5/benches/atomic_cell.rs b/third_party/rust/crossbeam-utils-0.7.2/benches/atomic_cell.rs similarity index 75% rename from third_party/rust/crossbeam-utils-0.6.5/benches/atomic_cell.rs rename to third_party/rust/crossbeam-utils-0.7.2/benches/atomic_cell.rs index aae17d41192a93708fb07821b57012407a957dbf..8587dba1d9f4a4c792c423a3dce377d75fa9e402 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/benches/atomic_cell.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/benches/atomic_cell.rs @@ -51,20 +51,18 @@ fn concurrent_load_u8(b: &mut test::Bencher) { thread::scope(|scope| { for _ in 0..THREADS { - scope.spawn(|_| { - loop { - start.wait(); - - let mut sum = 0; - for _ in 0..STEPS { - sum += a.load(); - } - test::black_box(sum); - - end.wait(); - if exit.load() { - break; - } + scope.spawn(|_| loop { + start.wait(); + + let mut sum = 0; + for _ in 0..STEPS { + sum += a.load(); + } + test::black_box(sum); + + end.wait(); + if exit.load() { + break; } }); } @@ -80,7 +78,8 @@ fn concurrent_load_u8(b: &mut test::Bencher) { start.wait(); exit.store(true); end.wait(); - }).unwrap(); + }) + .unwrap(); } #[bench] @@ -126,20 +125,18 @@ fn concurrent_load_usize(b: &mut test::Bencher) { thread::scope(|scope| { for _ in 0..THREADS { - scope.spawn(|_| { - loop { - start.wait(); - - let mut sum = 0; - for _ in 0..STEPS { - sum += a.load(); - } - test::black_box(sum); - - end.wait(); - if exit.load() { - break; - } + scope.spawn(|_| loop { + start.wait(); + + let mut sum = 0; + for _ in 0..STEPS { + sum += a.load(); + } + test::black_box(sum); + + end.wait(); + if exit.load() { + break; } }); } @@ -155,5 +152,6 @@ fn concurrent_load_usize(b: &mut test::Bencher) { start.wait(); exit.store(true); end.wait(); - }).unwrap(); + }) + .unwrap(); } diff --git a/third_party/rust/crossbeam-utils-0.7.2/build.rs b/third_party/rust/crossbeam-utils-0.7.2/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..2f5012ad763a3879de94b0ffd7d0a9aa277b770d --- /dev/null +++ b/third_party/rust/crossbeam-utils-0.7.2/build.rs @@ -0,0 +1,14 @@ +extern crate autocfg; + +fn main() { + let cfg = autocfg::new(); + if cfg.probe_rustc_version(1, 31) { + autocfg::emit("has_min_const_fn"); + } + + cfg.emit_type_cfg("core::sync::atomic::AtomicU8", "has_atomic_u8"); + cfg.emit_type_cfg("core::sync::atomic::AtomicU16", "has_atomic_u16"); + cfg.emit_type_cfg("core::sync::atomic::AtomicU32", "has_atomic_u32"); + cfg.emit_type_cfg("core::sync::atomic::AtomicU64", "has_atomic_u64"); + cfg.emit_type_cfg("core::sync::atomic::AtomicU128", "has_atomic_u128"); +} diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/atomic/atomic_cell.rs b/third_party/rust/crossbeam-utils-0.7.2/src/atomic/atomic_cell.rs similarity index 92% rename from third_party/rust/crossbeam-utils-0.7.0/src/atomic/atomic_cell.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/atomic/atomic_cell.rs index 76aae65f8a83f5654c1ef2ee12cf895e9c197795..cf0658aad4582949db6e92fd85fe4082ad61670a 100644 --- a/third_party/rust/crossbeam-utils-0.7.0/src/atomic/atomic_cell.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/src/atomic/atomic_cell.rs @@ -519,37 +519,28 @@ macro_rules! impl_arithmetic { } } }; - ($t:ty, $size:tt, $atomic:ty, $example:tt) => { - #[cfg(target_has_atomic = $size)] - impl_arithmetic!($t, $atomic, $example); - }; } -cfg_if! { - if #[cfg(feature = "nightly")] { - impl_arithmetic!(u8, "8", atomic::AtomicU8, "let a = AtomicCell::new(7u8);"); - impl_arithmetic!(i8, "8", atomic::AtomicI8, "let a = AtomicCell::new(7i8);"); - impl_arithmetic!(u16, "16", atomic::AtomicU16, "let a = AtomicCell::new(7u16);"); - impl_arithmetic!(i16, "16", atomic::AtomicI16, "let a = AtomicCell::new(7i16);"); - impl_arithmetic!(u32, "32", atomic::AtomicU32, "let a = AtomicCell::new(7u32);"); - impl_arithmetic!(i32, "32", atomic::AtomicI32, "let a = AtomicCell::new(7i32);"); - impl_arithmetic!(u64, "64", atomic::AtomicU64, "let a = AtomicCell::new(7u64);"); - impl_arithmetic!(i64, "64", atomic::AtomicI64, "let a = AtomicCell::new(7i64);"); - impl_arithmetic!(u128, "let a = AtomicCell::new(7u128);"); - impl_arithmetic!(i128, "let a = AtomicCell::new(7i128);"); - } else { - impl_arithmetic!(u8, "let a = AtomicCell::new(7u8);"); - impl_arithmetic!(i8, "let a = AtomicCell::new(7i8);"); - impl_arithmetic!(u16, "let a = AtomicCell::new(7u16);"); - impl_arithmetic!(i16, "let a = AtomicCell::new(7i16);"); - impl_arithmetic!(u32, "let a = AtomicCell::new(7u32);"); - impl_arithmetic!(i32, "let a = AtomicCell::new(7i32);"); - impl_arithmetic!(u64, "let a = AtomicCell::new(7u64);"); - impl_arithmetic!(i64, "let a = AtomicCell::new(7i64);"); - impl_arithmetic!(u128, "let a = AtomicCell::new(7u128);"); - impl_arithmetic!(i128, "let a = AtomicCell::new(7i128);"); - } -} +#[cfg(has_atomic_u8)] +impl_arithmetic!(u8, atomic::AtomicU8, "let a = AtomicCell::new(7u8);"); +#[cfg(has_atomic_u8)] +impl_arithmetic!(i8, atomic::AtomicI8, "let a = AtomicCell::new(7i8);"); +#[cfg(has_atomic_u16)] +impl_arithmetic!(u16, atomic::AtomicU16, "let a = AtomicCell::new(7u16);"); +#[cfg(has_atomic_u16)] +impl_arithmetic!(i16, atomic::AtomicI16, "let a = AtomicCell::new(7i16);"); +#[cfg(has_atomic_u32)] +impl_arithmetic!(u32, atomic::AtomicU32, "let a = AtomicCell::new(7u32);"); +#[cfg(has_atomic_u32)] +impl_arithmetic!(i32, atomic::AtomicI32, "let a = AtomicCell::new(7i32);"); +#[cfg(has_atomic_u64)] +impl_arithmetic!(u64, atomic::AtomicU64, "let a = AtomicCell::new(7u64);"); +#[cfg(has_atomic_u64)] +impl_arithmetic!(i64, atomic::AtomicI64, "let a = AtomicCell::new(7i64);"); +#[cfg(has_atomic_u128)] +impl_arithmetic!(u128, atomic::AtomicU128, "let a = AtomicCell::new(7u128);"); +#[cfg(has_atomic_u128)] +impl_arithmetic!(i128, atomic::AtomicI128, "let a = AtomicCell::new(7i128);"); impl_arithmetic!( usize, @@ -741,17 +732,14 @@ macro_rules! atomic { atomic!(@check, $t, AtomicUnit, $a, $atomic_op); atomic!(@check, $t, atomic::AtomicUsize, $a, $atomic_op); - #[cfg(feature = "nightly")] - { - #[cfg(target_has_atomic = "8")] - atomic!(@check, $t, atomic::AtomicU8, $a, $atomic_op); - #[cfg(target_has_atomic = "16")] - atomic!(@check, $t, atomic::AtomicU16, $a, $atomic_op); - #[cfg(target_has_atomic = "32")] - atomic!(@check, $t, atomic::AtomicU32, $a, $atomic_op); - #[cfg(target_has_atomic = "64")] - atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op); - } + #[cfg(has_atomic_u8)] + atomic!(@check, $t, atomic::AtomicU8, $a, $atomic_op); + #[cfg(has_atomic_u16)] + atomic!(@check, $t, atomic::AtomicU16, $a, $atomic_op); + #[cfg(has_atomic_u32)] + atomic!(@check, $t, atomic::AtomicU32, $a, $atomic_op); + #[cfg(has_atomic_u64)] + atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op); break $fallback_op; } diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/atomic/consume.rs b/third_party/rust/crossbeam-utils-0.7.2/src/atomic/consume.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/src/atomic/consume.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/atomic/consume.rs diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/atomic/mod.rs b/third_party/rust/crossbeam-utils-0.7.2/src/atomic/mod.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/src/atomic/mod.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/atomic/mod.rs diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/atomic/seq_lock.rs b/third_party/rust/crossbeam-utils-0.7.2/src/atomic/seq_lock.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/src/atomic/seq_lock.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/atomic/seq_lock.rs diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/atomic/seq_lock_wide.rs b/third_party/rust/crossbeam-utils-0.7.2/src/atomic/seq_lock_wide.rs similarity index 97% rename from third_party/rust/crossbeam-utils-0.7.0/src/atomic/seq_lock_wide.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/atomic/seq_lock_wide.rs index 090a849bd88c16a8a29706de44fcbbcafcd3b6bc..857c074f59d5a25f9a01a0f20ed40e8f835b36b7 100644 --- a/third_party/rust/crossbeam-utils-0.7.0/src/atomic/seq_lock_wide.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/src/atomic/seq_lock_wide.rs @@ -121,7 +121,9 @@ impl Drop for SeqLockWriteGuard { // Release ordering for synchronizing with `optimistic_read`. if state_lo == 0 { let state_hi = self.lock.state_hi.load(Ordering::Relaxed); - self.lock.state_hi.store(state_hi.wrapping_add(1), Ordering::Release); + self.lock + .state_hi + .store(state_hi.wrapping_add(1), Ordering::Release); } // Release the lock and increment the stamp. diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/backoff.rs b/third_party/rust/crossbeam-utils-0.7.2/src/backoff.rs similarity index 99% rename from third_party/rust/crossbeam-utils-0.6.5/src/backoff.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/backoff.rs index 49619917b1a2336b2a035702c847d2dfd95397a2..446755bbc7b4841ac8847cfee49cef8ff2de7894 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/src/backoff.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/src/backoff.rs @@ -93,9 +93,7 @@ impl Backoff { /// ``` #[inline] pub fn new() -> Self { - Backoff { - step: Cell::new(0), - } + Backoff { step: Cell::new(0) } } /// Resets the `Backoff`. diff --git a/third_party/rust/crossbeam-utils-0.6.5/src/cache_padded.rs b/third_party/rust/crossbeam-utils-0.7.2/src/cache_padded.rs similarity index 64% rename from third_party/rust/crossbeam-utils-0.6.5/src/cache_padded.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/cache_padded.rs index a5f3bbc1ccd235fa61a00006b56f074efccb90cf..bb864a419121d7507675a4ab7bee06d4d62b7393 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/src/cache_padded.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/src/cache_padded.rs @@ -9,14 +9,22 @@ use core::ops::{Deref, DerefMut}; /// CPU cores. Use `CachePadded` to ensure updating one piece of data doesn't invalidate other /// cached data. /// -/// Cache lines are assumed to be 64 bytes on all architectures. -/// /// # Size and alignment /// -/// The size of `CachePadded<T>` is the smallest multiple of 64 bytes large enough to accommodate +/// Cache lines are assumed to be N bytes long, depending on the architecture: +/// +/// * On x86-64, N = 128. +/// * On all others, N = 64. +/// +/// Note that N is just a reasonable guess and is not guaranteed to match the actual cache line +/// length of the machine the program is running on. On modern Intel architectures, spatial +/// prefetcher is pulling pairs of 64-byte cache lines at a time, so we pessimistically assume that +/// cache lines are 128 bytes long. +/// +/// The size of `CachePadded<T>` is the smallest multiple of N bytes large enough to accommodate /// a value of type `T`. /// -/// The alignment of `CachePadded<T>` is the maximum of 64 bytes and the alignment of `T`. +/// The alignment of `CachePadded<T>` is the maximum of N bytes and the alignment of `T`. /// /// # Examples /// @@ -25,11 +33,11 @@ use core::ops::{Deref, DerefMut}; /// ``` /// use crossbeam_utils::CachePadded; /// -/// let array = [CachePadded::new(1i32), CachePadded::new(2i32)]; -/// let addr1 = &*array[0] as *const i32 as usize; -/// let addr2 = &*array[1] as *const i32 as usize; +/// let array = [CachePadded::new(1i8), CachePadded::new(2i8)]; +/// let addr1 = &*array[0] as *const i8 as usize; +/// let addr2 = &*array[1] as *const i8 as usize; /// -/// assert_eq!(addr2 - addr1, 64); +/// assert!(addr2 - addr1 >= 64); /// assert_eq!(addr1 % 64, 0); /// assert_eq!(addr2 % 64, 0); /// ``` @@ -49,7 +57,14 @@ use core::ops::{Deref, DerefMut}; /// } /// ``` #[derive(Clone, Copy, Default, Hash, PartialEq, Eq)] -#[repr(align(64))] +// Starting from Intel's Sandy Bridge, spatial prefetcher is now pulling pairs of 64-byte cache +// lines at a time, so we have to align to 128 bytes rather than 64. +// +// Sources: +// - https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf +// - https://github.com/facebook/folly/blob/1b5288e6eea6df074758f877c849b6e73bbb9fbb/folly/lang/Align.h#L107 +#[cfg_attr(target_arch = "x86_64", repr(align(128)))] +#[cfg_attr(not(target_arch = "x86_64"), repr(align(64)))] pub struct CachePadded<T> { value: T, } @@ -71,7 +86,7 @@ impl<T> CachePadded<T> { CachePadded::<T> { value: t } } - /// Returns the value value. + /// Returns the inner value. /// /// # Examples /// diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/lib.rs b/third_party/rust/crossbeam-utils-0.7.2/src/lib.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/src/lib.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/lib.rs diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/sync/mod.rs b/third_party/rust/crossbeam-utils-0.7.2/src/sync/mod.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/src/sync/mod.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/sync/mod.rs index 31c8ffec4dfb8f8391954523b1bdebd87b1625e0..3634963725f8c0c9de945f698a4652f599c01ca8 100644 --- a/third_party/rust/crossbeam-utils-0.7.0/src/sync/mod.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/src/sync/mod.rs @@ -12,6 +12,6 @@ mod parker; mod sharded_lock; mod wait_group; -pub use self::sharded_lock::{ShardedLock, ShardedLockReadGuard, ShardedLockWriteGuard}; pub use self::parker::{Parker, Unparker}; +pub use self::sharded_lock::{ShardedLock, ShardedLockReadGuard, ShardedLockWriteGuard}; pub use self::wait_group::WaitGroup; diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/sync/parker.rs b/third_party/rust/crossbeam-utils-0.7.2/src/sync/parker.rs similarity index 96% rename from third_party/rust/crossbeam-utils-0.7.0/src/sync/parker.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/sync/parker.rs index 506db8e39318a473b9eb8a4bd63194c2fa69a536..051afe512da82ebd3fcca664ea0f648752d4ec4d 100644 --- a/third_party/rust/crossbeam-utils-0.7.0/src/sync/parker.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/src/sync/parker.rs @@ -1,8 +1,8 @@ use std::fmt; use std::marker::PhantomData; -use std::sync::{Arc, Condvar, Mutex}; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::SeqCst; +use std::sync::{Arc, Condvar, Mutex}; use std::time::Duration; /// A thread parking primitive. @@ -228,7 +228,11 @@ struct Inner { impl Inner { fn park(&self, timeout: Option<Duration>) { // If we were previously notified then we consume this notification and return quickly. - if self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() { + if self + .state + .compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst) + .is_ok() + { return; } @@ -266,7 +270,7 @@ impl Inner { match self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst) { Ok(_) => return, // got a notification - Err(_) => {} // spurious wakeup, go back to sleep + Err(_) => {} // spurious wakeup, go back to sleep } } } @@ -278,7 +282,7 @@ impl Inner { match self.state.swap(EMPTY, SeqCst) { NOTIFIED => {} // got a notification - PARKED => {} // no notification + PARKED => {} // no notification n => panic!("inconsistent park_timeout state: {}", n), } } @@ -291,9 +295,9 @@ impl Inner { // `NOTIFIED` even if `state` is already `NOTIFIED`. That is why this must be a swap rather // than a compare-and-swap that returns if it reads `NOTIFIED` on failure. match self.state.swap(NOTIFIED, SeqCst) { - EMPTY => return, // no one was waiting + EMPTY => return, // no one was waiting NOTIFIED => return, // already unparked - PARKED => {} // gotta go wake someone up + PARKED => {} // gotta go wake someone up _ => panic!("inconsistent state in unpark"), } diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/sync/sharded_lock.rs b/third_party/rust/crossbeam-utils-0.7.2/src/sync/sharded_lock.rs similarity index 96% rename from third_party/rust/crossbeam-utils-0.7.0/src/sync/sharded_lock.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/sync/sharded_lock.rs index 0fbb29175fd5deafbace49353658475de50f7237..bd269d1584c5e72bbb06b0898216676475d5bec8 100644 --- a/third_party/rust/crossbeam-utils-0.7.0/src/sync/sharded_lock.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/src/sync/sharded_lock.rs @@ -5,8 +5,8 @@ use std::marker::PhantomData; use std::mem; use std::ops::{Deref, DerefMut}; use std::panic::{RefUnwindSafe, UnwindSafe}; -use std::sync::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::sync::{LockResult, PoisonError, TryLockError, TryLockResult}; +use std::sync::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::thread::{self, ThreadId}; use CachePadded; @@ -99,10 +99,12 @@ impl<T> ShardedLock<T> { pub fn new(value: T) -> ShardedLock<T> { ShardedLock { shards: (0..NUM_SHARDS) - .map(|_| CachePadded::new(Shard { - lock: RwLock::new(()), - write_guard: UnsafeCell::new(None), - })) + .map(|_| { + CachePadded::new(Shard { + lock: RwLock::new(()), + write_guard: UnsafeCell::new(None), + }) + }) .collect::<Vec<_>>() .into_boxed_slice(), value: UnsafeCell::new(value), @@ -232,7 +234,7 @@ impl<T: ?Sized> ShardedLock<T> { _marker: PhantomData, }; Err(TryLockError::Poisoned(PoisonError::new(guard))) - }, + } Err(TryLockError::WouldBlock) => Err(TryLockError::WouldBlock), } } @@ -317,7 +319,7 @@ impl<T: ?Sized> ShardedLock<T> { Err(TryLockError::Poisoned(err)) => { poisoned = true; err.into_inner() - }, + } Err(TryLockError::WouldBlock) => { blocked = Some(i); break; @@ -416,10 +418,14 @@ impl<T: ?Sized> ShardedLock<T> { impl<T: ?Sized + fmt::Debug> fmt::Debug for ShardedLock<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.try_read() { - Ok(guard) => f.debug_struct("ShardedLock").field("data", &&*guard).finish(), - Err(TryLockError::Poisoned(err)) => { - f.debug_struct("ShardedLock").field("data", &&**err.get_ref()).finish() - }, + Ok(guard) => f + .debug_struct("ShardedLock") + .field("data", &&*guard) + .finish(), + Err(TryLockError::Poisoned(err)) => f + .debug_struct("ShardedLock") + .field("data", &&**err.get_ref()) + .finish(), Err(TryLockError::WouldBlock) => { struct LockedPlaceholder; impl fmt::Debug for LockedPlaceholder { @@ -427,7 +433,9 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for ShardedLock<T> { f.write_str("<locked>") } } - f.debug_struct("ShardedLock").field("data", &LockedPlaceholder).finish() + f.debug_struct("ShardedLock") + .field("data", &LockedPlaceholder) + .finish() } } } diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/sync/wait_group.rs b/third_party/rust/crossbeam-utils-0.7.2/src/sync/wait_group.rs similarity index 97% rename from third_party/rust/crossbeam-utils-0.7.0/src/sync/wait_group.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/sync/wait_group.rs index 16ddc3091c03f88543e5e71d13a159336ff15acd..0527b31593d5d442783d1bb67274d8b78db26d28 100644 --- a/third_party/rust/crossbeam-utils-0.7.0/src/sync/wait_group.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/src/sync/wait_group.rs @@ -132,8 +132,6 @@ impl Clone for WaitGroup { impl fmt::Debug for WaitGroup { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let count: &usize = &*self.inner.count.lock().unwrap(); - f.debug_struct("WaitGroup") - .field("count", count) - .finish() + f.debug_struct("WaitGroup").field("count", count).finish() } } diff --git a/third_party/rust/crossbeam-utils-0.7.0/src/thread.rs b/third_party/rust/crossbeam-utils-0.7.2/src/thread.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/src/thread.rs rename to third_party/rust/crossbeam-utils-0.7.2/src/thread.rs diff --git a/third_party/rust/crossbeam-utils-0.6.5/tests/atomic_cell.rs b/third_party/rust/crossbeam-utils-0.7.2/tests/atomic_cell.rs similarity index 81% rename from third_party/rust/crossbeam-utils-0.6.5/tests/atomic_cell.rs rename to third_party/rust/crossbeam-utils-0.7.2/tests/atomic_cell.rs index 37c901f04288da4019ff2845312609d7e95f6485..e0b7db525b652ebd847aeae7f199b5536d8abbe2 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/tests/atomic_cell.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/tests/atomic_cell.rs @@ -9,20 +9,19 @@ use crossbeam_utils::atomic::AtomicCell; fn is_lock_free() { struct UsizeWrap(usize); struct U8Wrap(bool); + struct I16Wrap(i16); assert_eq!(AtomicCell::<usize>::is_lock_free(), true); assert_eq!(AtomicCell::<isize>::is_lock_free(), true); assert_eq!(AtomicCell::<UsizeWrap>::is_lock_free(), true); - assert_eq!(AtomicCell::<u8>::is_lock_free(), cfg!(feature = "nightly")); - assert_eq!( - AtomicCell::<bool>::is_lock_free(), - cfg!(feature = "nightly") - ); - assert_eq!( - AtomicCell::<U8Wrap>::is_lock_free(), - cfg!(feature = "nightly") - ); + assert_eq!(AtomicCell::<u8>::is_lock_free(), cfg!(has_atomic_u8)); + assert_eq!(AtomicCell::<bool>::is_lock_free(), cfg!(has_atomic_u8)); + assert_eq!(AtomicCell::<U8Wrap>::is_lock_free(), cfg!(has_atomic_u8)); + + assert_eq!(AtomicCell::<I16Wrap>::is_lock_free(), cfg!(has_atomic_u16)); + + assert_eq!(AtomicCell::<u128>::is_lock_free(), cfg!(has_atomic_u128)); } #[test] @@ -206,3 +205,29 @@ fn modular_usize() { assert_eq!(a.compare_exchange(Foo(10), Foo(15)), Ok(Foo(100))); assert_eq!(a.load().0, 15); } + +#[test] +fn garbage_padding() { + #[derive(Copy, Clone, Eq, PartialEq)] + struct Object { + a: i64, + b: i32, + } + + let cell = AtomicCell::new(Object { a: 0, b: 0 }); + let _garbage = [0xfe, 0xfe, 0xfe, 0xfe, 0xfe]; // Needed + let next = Object { a: 0, b: 0 }; + + let prev = cell.load(); + assert!(cell.compare_exchange(prev, next).is_ok()); + println!(); +} + +#[cfg(has_min_const_fn)] +#[test] +fn const_atomic_cell_new() { + static CELL: AtomicCell<usize> = AtomicCell::new(0); + + CELL.store(1); + assert_eq!(CELL.load(), 1); +} diff --git a/third_party/rust/crossbeam-utils-0.7.0/tests/cache_padded.rs b/third_party/rust/crossbeam-utils-0.7.2/tests/cache_padded.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/tests/cache_padded.rs rename to third_party/rust/crossbeam-utils-0.7.2/tests/cache_padded.rs diff --git a/third_party/rust/crossbeam-utils-0.6.5/tests/parker.rs b/third_party/rust/crossbeam-utils-0.7.2/tests/parker.rs similarity index 96% rename from third_party/rust/crossbeam-utils-0.6.5/tests/parker.rs rename to third_party/rust/crossbeam-utils-0.7.2/tests/parker.rs index fab07b3a3c7a944c5cd8d3dab55e945898e4a972..3f4514626a2a235dabcc02ab4d9fa22c9f7686b9 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/tests/parker.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/tests/parker.rs @@ -37,6 +37,7 @@ fn park_timeout_unpark_called_other_thread() { }); p.park_timeout(Duration::from_millis(u32::MAX as u64)); - }).unwrap(); + }) + .unwrap(); } } diff --git a/third_party/rust/crossbeam-utils-0.6.5/tests/sharded_lock.rs b/third_party/rust/crossbeam-utils-0.7.2/tests/sharded_lock.rs similarity index 95% rename from third_party/rust/crossbeam-utils-0.6.5/tests/sharded_lock.rs rename to third_party/rust/crossbeam-utils-0.7.2/tests/sharded_lock.rs index 374c3c36cc8e76ac5a6db6c6f73f0121a0b55f3e..c98de799983923c8d305214580cc8f1f7b306b46 100644 --- a/third_party/rust/crossbeam-utils-0.6.5/tests/sharded_lock.rs +++ b/third_party/rust/crossbeam-utils-0.7.2/tests/sharded_lock.rs @@ -1,10 +1,10 @@ extern crate crossbeam_utils; extern crate rand; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::mpsc::channel; -use std::thread; use std::sync::{Arc, TryLockError}; -use std::sync::atomic::{AtomicUsize, Ordering}; +use std::thread; use crossbeam_utils::sync::ShardedLock; use rand::Rng; @@ -55,7 +55,8 @@ fn arc_poison_wr() { let _: Result<(), _> = thread::spawn(move || { let _lock = arc2.write().unwrap(); panic!(); - }).join(); + }) + .join(); assert!(arc.read().is_err()); } @@ -67,7 +68,8 @@ fn arc_poison_ww() { let _: Result<(), _> = thread::spawn(move || { let _lock = arc2.write().unwrap(); panic!(); - }).join(); + }) + .join(); assert!(arc.write().is_err()); assert!(arc.is_poisoned()); } @@ -79,7 +81,8 @@ fn arc_no_poison_rr() { let _: Result<(), _> = thread::spawn(move || { let _lock = arc2.read().unwrap(); panic!(); - }).join(); + }) + .join(); let lock = arc.read().unwrap(); assert_eq!(*lock, 1); } @@ -90,7 +93,8 @@ fn arc_no_poison_sl() { let _: Result<(), _> = thread::spawn(move || { let _lock = arc2.read().unwrap(); panic!() - }).join(); + }) + .join(); let lock = arc.write().unwrap(); assert_eq!(*lock, 1); } @@ -149,7 +153,8 @@ fn arc_access_in_unwind() { } let _u = Unwinder { i: arc2 }; panic!(); - }).join(); + }) + .join(); let lock = arc.read().unwrap(); assert_eq!(*lock, 2); } @@ -174,7 +179,10 @@ fn try_write() { let write_result = lock.try_write(); match write_result { Err(TryLockError::WouldBlock) => (), - Ok(_) => assert!(false, "try_write should not succeed while read_guard is in scope"), + Ok(_) => assert!( + false, + "try_write should not succeed while read_guard is in scope" + ), Err(_) => assert!(false, "unexpected error"), } @@ -212,7 +220,8 @@ fn test_into_inner_poison() { let _ = thread::spawn(move || { let _lock = m2.write().unwrap(); panic!("test panic in inner thread to poison ShardedLock"); - }).join(); + }) + .join(); assert!(m.is_poisoned()); match Arc::try_unwrap(m).unwrap().into_inner() { @@ -235,7 +244,8 @@ fn test_get_mut_poison() { let _ = thread::spawn(move || { let _lock = m2.write().unwrap(); panic!("test panic in inner thread to poison ShardedLock"); - }).join(); + }) + .join(); assert!(m.is_poisoned()); match Arc::try_unwrap(m).unwrap().get_mut() { diff --git a/third_party/rust/crossbeam-utils-0.7.0/tests/thread.rs b/third_party/rust/crossbeam-utils-0.7.2/tests/thread.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/tests/thread.rs rename to third_party/rust/crossbeam-utils-0.7.2/tests/thread.rs diff --git a/third_party/rust/crossbeam-utils-0.7.0/tests/wait_group.rs b/third_party/rust/crossbeam-utils-0.7.2/tests/wait_group.rs similarity index 100% rename from third_party/rust/crossbeam-utils-0.7.0/tests/wait_group.rs rename to third_party/rust/crossbeam-utils-0.7.2/tests/wait_group.rs diff --git a/third_party/rust/crossbeam-utils/.cargo-checksum.json b/third_party/rust/crossbeam-utils/.cargo-checksum.json index 9a264617eedb56bf367c8c5fcdd0279d7863ae06..4ffc417110012eef096e595607e1fea92feb1450 100644 --- a/third_party/rust/crossbeam-utils/.cargo-checksum.json +++ b/third_party/rust/crossbeam-utils/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"CHANGELOG.md":"36557d1a612004b5108ed46be3716bb2e06368d5bb0cd9e7ea4b6bcc4d81c07a","Cargo.toml":"648a34c3609f0cb729929fd5c6d1288475232a4daeb79363e629ecadcc5d3a4f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"5bbcf23ea854d44870790a316dbcdb8d7b0c2e0f17a521e8d4fbffdd9dd5b464","benches/atomic_cell.rs":"de327015cf811fb74b7a624719f678ba0677025dc703d56cbd2094a3c92da23b","build.rs":"f927f9796b0cbae832f458e82833b24c7ced9f27f4f1e76de9d11ad30d21c88a","src/atomic/atomic_cell.rs":"4b86367084da93176c335650524220ef7b3df4df09b6535d0b55a03446dee7e0","src/atomic/consume.rs":"1ee5de160b6e3755c02940c24fa90f85f3ef2f7afb971e9e9c6f481609bbc7b7","src/atomic/mod.rs":"c84d068944388c1385d6fec9211b6be26c777a21fc04e7231d1f3b564de62708","src/atomic/seq_lock.rs":"ee50097cd582cfe6e28ebc54935fc6488f52e2fed19d4b26bafd5eab5c229291","src/atomic/seq_lock_wide.rs":"f03ee779c2ebebcfb0df8baac49be7d38e920876260c8da9dff0fc894068c35d","src/backoff.rs":"98d1daee75bbd6243bc0784c92c56086e57658baff93a2a1f0729426901c03ee","src/cache_padded.rs":"5671f3a02f6e407f1dc562d4fb17e4659f18d1e5206b8566b38d2e447e5f6fa4","src/lib.rs":"61c6bc2b43d87550c4547693f3eacfe126581560a8884b32b23f01a7e2c6d833","src/sync/mod.rs":"e5f4087c4e63b0e6e0b291f3946a224aa9d2a4a0c299c23014b822d6346f6986","src/sync/parker.rs":"6137fccce8c03045440cbc3166721e4e4b5f73013165c9c260cff904cfcab6f3","src/sync/sharded_lock.rs":"14be659744918d0b27db24c56b41c618b0f0484b6761da46561023d96c4c120f","src/sync/wait_group.rs":"932e11753764b238f764892978a6b70fb288111faf7fae7766e603bed4e5b444","src/thread.rs":"6c44bf4c4515a769b8ccd0c9d9b80f5b46bd4768ec323a909773301d375033fb","tests/atomic_cell.rs":"5efe71777d7687ee01e387d5ca20436c3e8171e1e879a63074d1f79ccc88ff5e","tests/cache_padded.rs":"6ba6ad1b3060bfb2f7bf0a1d006f949d91c49e506564b0d28e4f06129b94665d","tests/parker.rs":"a1f63cf99b3524bfc91d0797133d0b75165445ecbaa92f78bd8101fa7cc828ec","tests/sharded_lock.rs":"c7d9f7185900b3ff84d00f5252793d5d28c47374678b8e6f758a67fa32c71fca","tests/thread.rs":"9a7d7d3028c552fd834c68598b04a1cc252a816bc20ab62cec060d6cd09cab10","tests/wait_group.rs":"ad8f0cdfed31f9594a2e0737234d418f8b924d784a4db8d7e469deab8c95f5f8"},"package":"02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"} \ No newline at end of file +{"files":{"CHANGELOG.md":"5242f1740c65509c465c9a36326d344722facff5f5e58dd064f7b77806b83a46","Cargo.toml":"ac35a7b8ccb16f1ab256951576537aa4179a316c068929c2acef89e0adc12319","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"5734ed989dfca1f625b40281ee9f4530f91b2411ec01cb748223e7eb87e201ab","README.md":"dfa9fbed47c344c134a63c84b7c0e4651baeac1554b7b3266d0e38643743fc33","benches/atomic_cell.rs":"c927eb3cd1e5ecc4b91adbc3bde98af15ffab4086190792ba64d5cde0e24df3d","build.rs":"68cfc4be02429834a19411fba29cb1cb52c841f03ac8104d1bae59a8b2184f9c","no_atomic.rs":"a2621c1b029c614fb0ab8e3f5cda2e839df88d90d26133181c1b901965f7eec4","src/atomic/atomic_cell.rs":"1a3a1e073340317b5ce7a94e29c6a87db89ff7e00da6b92cb3c0339364c3b084","src/atomic/consume.rs":"7a7736fcd64f6473dfea7653559ffc5e1a2a234df43835f8aa8734862145ac15","src/atomic/mod.rs":"7f6afd5bd0da1f7b51765ab04da4e5f683588ac2d23506e61bf7007bb1e61ba2","src/atomic/seq_lock.rs":"27182e6b87a9db73c5f6831759f8625f9fcdec3c2828204c444aef04f427735a","src/atomic/seq_lock_wide.rs":"9888dd03116bb89ca36d4ab8d5a0b5032107a2983a7eb8024454263b09080088","src/backoff.rs":"7cc7754e15f69b52e92a70d4f49d1bc274693455a0933a2d7eb0605806566af3","src/cache_padded.rs":"6a512698115ad0d5a5b163dbd7a83247e1f1c146c4a30f3fc74b952e3b767b59","src/lib.rs":"6f1bcf157abe06ad8458a53e865bf8efab9fad4a9424790147cee8fefb3795d8","src/sync/mod.rs":"59986f559a8f170a4b3247ab2eea2460b09809d87c8110ed88e4e7103d3519dc","src/sync/parker.rs":"ba8f75bff31b8be9275808e8f393e71cc682dfc1109ceccb12f69a3700cff5be","src/sync/sharded_lock.rs":"14be659744918d0b27db24c56b41c618b0f0484b6761da46561023d96c4c120f","src/sync/wait_group.rs":"32e946a7581c55f8aa9904527b92b177c538fa0cf7cbcfa1d1f25990582cb6ea","src/thread.rs":"0eb5ec1d3c1b40600d88eb70539d14276e32307f5bed2b679f50f6a20777a01e","tests/atomic_cell.rs":"6c9453384ecbbe76f8b97b62f022d478d3a76b4eae1e960f49790970f5d52158","tests/cache_padded.rs":"1bfaff8354c8184e1ee1f902881ca9400b60effb273b0d3f752801a483d2b66d","tests/parker.rs":"6def4721287d9d70b1cfd63ebb34e1c83fbb3376edbad2bc8aac6ef69dd99d20","tests/sharded_lock.rs":"726025ce6351fb56ed629d5a56bdf6e833b7afc5dedfa08de0b056c726b6c26d","tests/thread.rs":"9a7d7d3028c552fd834c68598b04a1cc252a816bc20ab62cec060d6cd09cab10","tests/wait_group.rs":"ad8f0cdfed31f9594a2e0737234d418f8b924d784a4db8d7e469deab8c95f5f8"},"package":"d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"} \ No newline at end of file diff --git a/third_party/rust/crossbeam-utils/CHANGELOG.md b/third_party/rust/crossbeam-utils/CHANGELOG.md index a17c6e6f15d57c983e53095e65284a568345438f..8c485ef6b1a07a0b4f0ea4c6d3ac0adada8fb2f9 100644 --- a/third_party/rust/crossbeam-utils/CHANGELOG.md +++ b/third_party/rust/crossbeam-utils/CHANGELOG.md @@ -1,3 +1,23 @@ +# Version 0.8.5 + +- Add `AtomicCell::fetch_update` (#704) +- Support targets that do not have atomic CAS on stable Rust (#698) + +# Version 0.8.4 + +- Bump `loom` dependency to version 0.5. (#686) + +# Version 0.8.3 + +- Make `loom` dependency optional. (#666) + +# Version 0.8.2 + +- Deprecate `AtomicCell::compare_and_swap`. Use `AtomicCell::compare_exchange` instead. (#619) +- Add `Parker::park_deadline`. (#563) +- Improve implementation of `CachePadded`. (#636) +- Add unstable support for `loom`. (#487) + # Version 0.8.1 - Make `AtomicCell::is_lock_free` always const fn. (#600) @@ -8,7 +28,7 @@ # Version 0.8.0 - Bump the minimum supported Rust version to 1.36. -- Remove deprecated `AtomicCell::get_mut()` and `Backoff::is_complete()` methods +- Remove deprecated `AtomicCell::get_mut()` and `Backoff::is_complete()` methods. - Remove `alloc` feature. - Make `CachePadded::new()` const function. - Make `AtomicCell::is_lock_free()` const function at 1.46+. diff --git a/third_party/rust/crossbeam-utils/Cargo.toml b/third_party/rust/crossbeam-utils/Cargo.toml index edb08f9998e1923fae56c15d0b0ea45efc0d3ea6..0b32b467165ec7ef31f44c2fe7454ccda3f13567 100644 --- a/third_party/rust/crossbeam-utils/Cargo.toml +++ b/third_party/rust/crossbeam-utils/Cargo.toml @@ -13,12 +13,11 @@ [package] edition = "2018" name = "crossbeam-utils" -version = "0.8.1" +version = "0.8.5" authors = ["The Crossbeam Project Developers"] description = "Utilities for concurrent programming" homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils" documentation = "https://docs.rs/crossbeam-utils" -readme = "README.md" keywords = ["scoped", "thread", "atomic", "cache"] categories = ["algorithms", "concurrency", "data-structures", "no-std"] license = "MIT OR Apache-2.0" @@ -30,11 +29,12 @@ version = "1" version = "1.4.0" optional = true [dev-dependencies.rand] -version = "0.7.3" -[build-dependencies.autocfg] -version = "1.0.0" +version = "0.8" [features] default = ["std"] nightly = [] std = ["lazy_static"] +[target."cfg(crossbeam_loom)".dependencies.loom] +version = "0.5" +optional = true diff --git a/third_party/rust/crossbeam-utils/README.md b/third_party/rust/crossbeam-utils/README.md index 7e95829874e7f0ed958b3b45317b8897454b2af6..6e9a8e49a51a50a274e20321b0336d91abbe70ed 100644 --- a/third_party/rust/crossbeam-utils/README.md +++ b/third_party/rust/crossbeam-utils/README.md @@ -2,7 +2,7 @@ []( https://github.com/crossbeam-rs/crossbeam/actions) -[]( +[]( https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils#license) []( https://crates.io/crates/crossbeam-utils) @@ -10,7 +10,7 @@ https://crates.io/crates/crossbeam-utils) https://docs.rs/crossbeam-utils) []( https://www.rust-lang.org) -[](https://discord.gg/BBYwKq) +[](https://discord.com/invite/JXYwgWZ) This crate provides miscellaneous tools for concurrent programming: diff --git a/third_party/rust/crossbeam-utils/benches/atomic_cell.rs b/third_party/rust/crossbeam-utils/benches/atomic_cell.rs index 938a8fe3809802324a44617d6e708002454ee24d..844f7c02b63e1f370319a07e305ff2dfa593950b 100644 --- a/third_party/rust/crossbeam-utils/benches/atomic_cell.rs +++ b/third_party/rust/crossbeam-utils/benches/atomic_cell.rs @@ -28,11 +28,11 @@ fn fetch_add_u8(b: &mut test::Bencher) { } #[bench] -fn compare_and_swap_u8(b: &mut test::Bencher) { +fn compare_exchange_u8(b: &mut test::Bencher) { let a = AtomicCell::new(0u8); let mut i = 0; b.iter(|| { - a.compare_and_swap(i, i.wrapping_add(1)); + let _ = a.compare_exchange(i, i.wrapping_add(1)); i = i.wrapping_add(1); }); } @@ -102,11 +102,11 @@ fn fetch_add_usize(b: &mut test::Bencher) { } #[bench] -fn compare_and_swap_usize(b: &mut test::Bencher) { +fn compare_exchange_usize(b: &mut test::Bencher) { let a = AtomicCell::new(0usize); let mut i = 0; b.iter(|| { - a.compare_and_swap(i, i.wrapping_add(1)); + let _ = a.compare_exchange(i, i.wrapping_add(1)); i = i.wrapping_add(1); }); } diff --git a/third_party/rust/crossbeam-utils/build.rs b/third_party/rust/crossbeam-utils/build.rs index 3e51021835a074e26d6c58b9a58080f8829fa312..9c924adeb734583879832e161e712e8b3df008ce 100644 --- a/third_party/rust/crossbeam-utils/build.rs +++ b/third_party/rust/crossbeam-utils/build.rs @@ -1,23 +1,40 @@ -use autocfg::AutoCfg; +#![warn(rust_2018_idioms)] + +use std::env; + +include!("no_atomic.rs"); // The rustc-cfg strings below are *not* public API. Please let us know by // opening a GitHub issue if your build environment requires some way to enable // these cfgs other than by executing our build script. fn main() { - let cfg = match AutoCfg::new() { - Ok(cfg) => cfg, + let target = match env::var("TARGET") { + Ok(target) => target, Err(e) => { println!( - "cargo:warning=crossbeam-utils: unable to determine rustc version: {}", + "cargo:warning={}: unable to get TARGET environment variable: {}", + env!("CARGO_PKG_NAME"), e ); return; } }; - cfg.emit_type_cfg("core::sync::atomic::AtomicU8", "has_atomic_u8"); - cfg.emit_type_cfg("core::sync::atomic::AtomicU16", "has_atomic_u16"); - cfg.emit_type_cfg("core::sync::atomic::AtomicU32", "has_atomic_u32"); - cfg.emit_type_cfg("core::sync::atomic::AtomicU64", "has_atomic_u64"); - cfg.emit_type_cfg("core::sync::atomic::AtomicU128", "has_atomic_u128"); + // 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. + if NO_ATOMIC_CAS.contains(&&*target) { + println!("cargo:rustc-cfg=crossbeam_no_atomic_cas"); + } + if NO_ATOMIC.contains(&&*target) { + println!("cargo:rustc-cfg=crossbeam_no_atomic"); + println!("cargo:rustc-cfg=crossbeam_no_atomic_64"); + } else if NO_ATOMIC_64.contains(&&*target) { + println!("cargo:rustc-cfg=crossbeam_no_atomic_64"); + } else { + // Otherwise, assuming `"max-atomic-width" == 64`. + } + + println!("cargo:rerun-if-changed=no_atomic.rs"); } diff --git a/third_party/rust/crossbeam-utils/no_atomic.rs b/third_party/rust/crossbeam-utils/no_atomic.rs new file mode 100644 index 0000000000000000000000000000000000000000..522b3b8acd8965eb7b1499eda20eb35fcd88a489 --- /dev/null +++ b/third_party/rust/crossbeam-utils/no_atomic.rs @@ -0,0 +1,59 @@ +// This file is @generated by no_atomic.sh. +// It is not intended for manual editing. + +const NO_ATOMIC_CAS: &[&str] = &[ + "avr-unknown-gnu-atmega328", + "msp430-none-elf", + "riscv32i-unknown-none-elf", + "riscv32imc-unknown-none-elf", + "thumbv4t-none-eabi", + "thumbv6m-none-eabi", +]; +#[allow(dead_code)] +const NO_ATOMIC_64: &[&str] = &[ + "arm-linux-androideabi", + "armebv7r-none-eabi", + "armebv7r-none-eabihf", + "armv4t-unknown-linux-gnueabi", + "armv5te-unknown-linux-gnueabi", + "armv5te-unknown-linux-musleabi", + "armv5te-unknown-linux-uclibceabi", + "armv7r-none-eabi", + "armv7r-none-eabihf", + "hexagon-unknown-linux-musl", + "mips-unknown-linux-gnu", + "mips-unknown-linux-musl", + "mips-unknown-linux-uclibc", + "mipsel-unknown-linux-gnu", + "mipsel-unknown-linux-musl", + "mipsel-unknown-linux-uclibc", + "mipsel-unknown-none", + "mipsisa32r6-unknown-linux-gnu", + "mipsisa32r6el-unknown-linux-gnu", + "powerpc-unknown-linux-gnu", + "powerpc-unknown-linux-gnuspe", + "powerpc-unknown-linux-musl", + "powerpc-unknown-netbsd", + "powerpc-unknown-openbsd", + "powerpc-wrs-vxworks", + "powerpc-wrs-vxworks-spe", + "riscv32gc-unknown-linux-gnu", + "riscv32gc-unknown-linux-musl", + "riscv32imac-unknown-none-elf", + "thumbv7em-none-eabi", + "thumbv7em-none-eabihf", + "thumbv7m-none-eabi", + "thumbv8m.base-none-eabi", + "thumbv8m.main-none-eabi", + "thumbv8m.main-none-eabihf", + "mipsel-sony-psp", + "thumbv4t-none-eabi", + "thumbv6m-none-eabi", +]; +#[allow(dead_code)] +const NO_ATOMIC: &[&str] = &[ + "avr-unknown-gnu-atmega328", + "msp430-none-elf", + "riscv32i-unknown-none-elf", + "riscv32imc-unknown-none-elf", +]; diff --git a/third_party/rust/crossbeam-utils/src/atomic/atomic_cell.rs b/third_party/rust/crossbeam-utils/src/atomic/atomic_cell.rs index e8f6804cfd274f0a9196f26af42dfee99a7a7ed7..1a1c46460187494af42996acc43f1e63ec4ebd6a 100644 --- a/third_party/rust/crossbeam-utils/src/atomic/atomic_cell.rs +++ b/third_party/rust/crossbeam-utils/src/atomic/atomic_cell.rs @@ -2,15 +2,19 @@ #![allow(clippy::unit_arg)] #![allow(clippy::let_unit_value)] +use crate::primitive::sync::atomic::{self, AtomicBool}; use core::cell::UnsafeCell; use core::fmt; use core::mem; +use core::sync::atomic::Ordering; + +#[cfg(not(crossbeam_loom))] use core::ptr; -use core::sync::atomic::{self, AtomicBool, Ordering}; #[cfg(feature = "std")] use std::panic::{RefUnwindSafe, UnwindSafe}; +#[cfg(not(crossbeam_loom))] use super::seq_lock::SeqLock; /// A thread-safe mutable memory location. @@ -213,6 +217,7 @@ impl<T: Copy + Eq> AtomicCell<T> { /// # Examples /// /// ``` + /// # #![allow(deprecated)] /// use crossbeam_utils::atomic::AtomicCell; /// /// let a = AtomicCell::new(1); @@ -223,6 +228,8 @@ impl<T: Copy + Eq> AtomicCell<T> { /// assert_eq!(a.compare_and_swap(1, 2), 1); /// assert_eq!(a.load(), 2); /// ``` + // TODO: remove in the next major version. + #[deprecated(note = "Use `compare_exchange` instead")] pub fn compare_and_swap(&self, current: T, new: T) -> T { match self.compare_exchange(current, new) { Ok(v) => v, @@ -251,6 +258,40 @@ impl<T: Copy + Eq> AtomicCell<T> { pub fn compare_exchange(&self, current: T, new: T) -> Result<T, T> { unsafe { atomic_compare_exchange_weak(self.value.get(), current, new) } } + + /// Fetches the value, and applies a function to it that returns an optional + /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else + /// `Err(previous_value)`. + /// + /// Note: This may call the function multiple times if the value has been changed from other threads in + /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied + /// only once to the stored value. + /// + /// # Examples + /// + /// ```rust + /// use crossbeam_utils::atomic::AtomicCell; + /// + /// let a = AtomicCell::new(7); + /// assert_eq!(a.fetch_update(|_| None), Err(7)); + /// assert_eq!(a.fetch_update(|a| Some(a + 1)), Ok(7)); + /// assert_eq!(a.fetch_update(|a| Some(a + 1)), Ok(8)); + /// assert_eq!(a.load(), 9); + /// ``` + #[inline] + pub fn fetch_update<F>(&self, mut f: F) -> Result<T, T> + where + F: FnMut(T) -> Option<T>, + { + let mut prev = self.load(); + while let Some(next) = f(prev) { + match self.compare_exchange(prev, next) { + x @ Ok(_) => return x, + Err(next_prev) => prev = next_prev, + } + } + Err(prev) + } } macro_rules! impl_arithmetic { @@ -490,26 +531,19 @@ macro_rules! impl_arithmetic { }; } -#[cfg(has_atomic_u8)] impl_arithmetic!(u8, atomic::AtomicU8, "let a = AtomicCell::new(7u8);"); -#[cfg(has_atomic_u8)] impl_arithmetic!(i8, atomic::AtomicI8, "let a = AtomicCell::new(7i8);"); -#[cfg(has_atomic_u16)] impl_arithmetic!(u16, atomic::AtomicU16, "let a = AtomicCell::new(7u16);"); -#[cfg(has_atomic_u16)] impl_arithmetic!(i16, atomic::AtomicI16, "let a = AtomicCell::new(7i16);"); -#[cfg(has_atomic_u32)] impl_arithmetic!(u32, atomic::AtomicU32, "let a = AtomicCell::new(7u32);"); -#[cfg(has_atomic_u32)] impl_arithmetic!(i32, atomic::AtomicI32, "let a = AtomicCell::new(7i32);"); -#[cfg(has_atomic_u64)] +#[cfg(not(crossbeam_no_atomic_64))] impl_arithmetic!(u64, atomic::AtomicU64, "let a = AtomicCell::new(7u64);"); -#[cfg(has_atomic_u64)] +#[cfg(not(crossbeam_no_atomic_64))] impl_arithmetic!(i64, atomic::AtomicI64, "let a = AtomicCell::new(7i64);"); -#[cfg(has_atomic_u128)] -impl_arithmetic!(u128, atomic::AtomicU128, "let a = AtomicCell::new(7u128);"); -#[cfg(has_atomic_u128)] -impl_arithmetic!(i128, atomic::AtomicI128, "let a = AtomicCell::new(7i128);"); +// TODO: AtomicU128 is unstable +// impl_arithmetic!(u128, atomic::AtomicU128, "let a = AtomicCell::new(7u128);"); +// impl_arithmetic!(i128, atomic::AtomicI128, "let a = AtomicCell::new(7i128);"); impl_arithmetic!( usize, @@ -624,6 +658,7 @@ const fn can_transmute<A, B>() -> bool { /// scalability. #[inline] #[must_use] +#[cfg(not(crossbeam_loom))] fn lock(addr: usize) -> &'static SeqLock { // The number of locks is a prime number because we want to make sure `addr % LEN` gets // dispersed across all locks. @@ -769,6 +804,7 @@ impl AtomicUnit { #[inline] fn swap(&self, _val: (), _order: Ordering) {} + #[allow(clippy::unnecessary_wraps)] // This is intentional. #[inline] fn compare_exchange_weak( &self, @@ -799,17 +835,17 @@ macro_rules! atomic { atomic!(@check, $t, AtomicUnit, $a, $atomic_op); atomic!(@check, $t, atomic::AtomicUsize, $a, $atomic_op); - #[cfg(has_atomic_u8)] atomic!(@check, $t, atomic::AtomicU8, $a, $atomic_op); - #[cfg(has_atomic_u16)] atomic!(@check, $t, atomic::AtomicU16, $a, $atomic_op); - #[cfg(has_atomic_u32)] atomic!(@check, $t, atomic::AtomicU32, $a, $atomic_op); - #[cfg(has_atomic_u64)] + #[cfg(not(crossbeam_no_atomic_64))] atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op); - #[cfg(has_atomic_u128)] - atomic!(@check, $t, atomic::AtomicU128, $a, $atomic_op); + // TODO: AtomicU128 is unstable + // atomic!(@check, $t, atomic::AtomicU128, $a, $atomic_op); + #[cfg(crossbeam_loom)] + unimplemented!("loom does not support non-atomic atomic ops"); + #[cfg(not(crossbeam_loom))] break $fallback_op; } }; @@ -818,17 +854,15 @@ macro_rules! atomic { /// Returns `true` if operations on `AtomicCell<T>` are lock-free. const fn atomic_is_lock_free<T>() -> bool { // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36. - let is_lock_free = can_transmute::<T, AtomicUnit>() | can_transmute::<T, atomic::AtomicUsize>(); - #[cfg(has_atomic_u8)] - let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU8>(); - #[cfg(has_atomic_u16)] - let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU16>(); - #[cfg(has_atomic_u32)] - let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU32>(); - #[cfg(has_atomic_u64)] + let is_lock_free = can_transmute::<T, AtomicUnit>() + | can_transmute::<T, atomic::AtomicUsize>() + | can_transmute::<T, atomic::AtomicU8>() + | can_transmute::<T, atomic::AtomicU16>() + | can_transmute::<T, atomic::AtomicU32>(); + #[cfg(not(crossbeam_no_atomic_64))] let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU64>(); - #[cfg(has_atomic_u128)] - let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>(); + // TODO: AtomicU128 is unstable + // let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>(); is_lock_free } diff --git a/third_party/rust/crossbeam-utils/src/atomic/consume.rs b/third_party/rust/crossbeam-utils/src/atomic/consume.rs index 584fc34c1ae6fe147a418cd48fe396e7ed248f0f..277b370a554b0d81f97fd011381e32b19ac72255 100644 --- a/third_party/rust/crossbeam-utils/src/atomic/consume.rs +++ b/third_party/rust/crossbeam-utils/src/atomic/consume.rs @@ -1,5 +1,6 @@ #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] -use core::sync::atomic::compiler_fence; +use crate::primitive::sync::atomic::compiler_fence; +#[cfg(not(crossbeam_no_atomic))] use core::sync::atomic::Ordering; /// Trait which allows reading from primitive atomic types with "consume" ordering. @@ -25,6 +26,7 @@ pub trait AtomicConsume { fn load_consume(&self) -> Self::Val; } +#[cfg(not(crossbeam_no_atomic))] #[cfg(any(target_arch = "arm", target_arch = "aarch64"))] macro_rules! impl_consume { () => { @@ -37,6 +39,7 @@ macro_rules! impl_consume { }; } +#[cfg(not(crossbeam_no_atomic))] #[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))] macro_rules! impl_consume { () => { @@ -49,7 +52,13 @@ macro_rules! impl_consume { macro_rules! impl_atomic { ($atomic:ident, $val:ty) => { - impl AtomicConsume for ::core::sync::atomic::$atomic { + #[cfg(not(crossbeam_no_atomic))] + impl AtomicConsume for core::sync::atomic::$atomic { + type Val = $val; + impl_consume!(); + } + #[cfg(crossbeam_loom)] + impl AtomicConsume for loom::sync::atomic::$atomic { type Val = $val; impl_consume!(); } @@ -59,24 +68,25 @@ macro_rules! impl_atomic { impl_atomic!(AtomicBool, bool); impl_atomic!(AtomicUsize, usize); impl_atomic!(AtomicIsize, isize); -#[cfg(has_atomic_u8)] impl_atomic!(AtomicU8, u8); -#[cfg(has_atomic_u8)] impl_atomic!(AtomicI8, i8); -#[cfg(has_atomic_u16)] impl_atomic!(AtomicU16, u16); -#[cfg(has_atomic_u16)] impl_atomic!(AtomicI16, i16); -#[cfg(has_atomic_u32)] impl_atomic!(AtomicU32, u32); -#[cfg(has_atomic_u32)] impl_atomic!(AtomicI32, i32); -#[cfg(has_atomic_u64)] +#[cfg(not(crossbeam_no_atomic_64))] impl_atomic!(AtomicU64, u64); -#[cfg(has_atomic_u64)] +#[cfg(not(crossbeam_no_atomic_64))] impl_atomic!(AtomicI64, i64); -impl<T> AtomicConsume for ::core::sync::atomic::AtomicPtr<T> { +#[cfg(not(crossbeam_no_atomic))] +impl<T> AtomicConsume for core::sync::atomic::AtomicPtr<T> { + type Val = *mut T; + impl_consume!(); +} + +#[cfg(crossbeam_loom)] +impl<T> AtomicConsume for loom::sync::atomic::AtomicPtr<T> { type Val = *mut T; impl_consume!(); } diff --git a/third_party/rust/crossbeam-utils/src/atomic/mod.rs b/third_party/rust/crossbeam-utils/src/atomic/mod.rs index 7309c166d27732f58064fe78c8397957b7319343..fc713fcac667b50e2ac02270f807549e75f8e54a 100644 --- a/third_party/rust/crossbeam-utils/src/atomic/mod.rs +++ b/third_party/rust/crossbeam-utils/src/atomic/mod.rs @@ -1,8 +1,11 @@ //! Atomic types. +//! +//! * [`AtomicCell`], a thread-safe mutable memory location. +//! * [`AtomicConsume`], for reading from primitive atomic types with "consume" ordering. -use cfg_if::cfg_if; - -cfg_if! { +#[cfg(not(crossbeam_no_atomic_cas))] +#[cfg(not(crossbeam_loom))] +cfg_if::cfg_if! { // Use "wide" sequence lock if the pointer width <= 32 for preventing its counter against wrap // around. // @@ -20,8 +23,10 @@ cfg_if! { } } +#[cfg(not(crossbeam_no_atomic_cas))] mod atomic_cell; mod consume; +#[cfg(not(crossbeam_no_atomic_cas))] pub use self::atomic_cell::AtomicCell; pub use self::consume::AtomicConsume; diff --git a/third_party/rust/crossbeam-utils/src/atomic/seq_lock.rs b/third_party/rust/crossbeam-utils/src/atomic/seq_lock.rs index a423bc0320b8aac14e437ac4daa5af22ced4b2f0..ff8defd26dab85c744fa1f3987f9d4c67dd568f1 100644 --- a/third_party/rust/crossbeam-utils/src/atomic/seq_lock.rs +++ b/third_party/rust/crossbeam-utils/src/atomic/seq_lock.rs @@ -4,7 +4,7 @@ use core::sync::atomic::{self, AtomicUsize, Ordering}; use crate::Backoff; /// A simple stamped lock. -pub struct SeqLock { +pub(crate) struct SeqLock { /// The current state of the lock. /// /// All bits except the least significant one hold the current stamp. When locked, the state @@ -13,7 +13,7 @@ pub struct SeqLock { } impl SeqLock { - pub const fn new() -> Self { + pub(crate) const fn new() -> Self { Self { state: AtomicUsize::new(0), } @@ -23,7 +23,7 @@ impl SeqLock { /// /// This method should be called before optimistic reads. #[inline] - pub fn optimistic_read(&self) -> Option<usize> { + pub(crate) fn optimistic_read(&self) -> Option<usize> { let state = self.state.load(Ordering::Acquire); if state == 1 { None @@ -37,14 +37,14 @@ impl SeqLock { /// This method should be called after optimistic reads to check whether they are valid. The /// argument `stamp` should correspond to the one returned by method `optimistic_read`. #[inline] - pub fn validate_read(&self, stamp: usize) -> bool { + pub(crate) fn validate_read(&self, stamp: usize) -> bool { atomic::fence(Ordering::Acquire); self.state.load(Ordering::Relaxed) == stamp } /// Grabs the lock for writing. #[inline] - pub fn write(&'static self) -> SeqLockWriteGuard { + pub(crate) fn write(&'static self) -> SeqLockWriteGuard { let backoff = Backoff::new(); loop { let previous = self.state.swap(1, Ordering::Acquire); @@ -64,7 +64,7 @@ impl SeqLock { } /// An RAII guard that releases the lock and increments the stamp when dropped. -pub struct SeqLockWriteGuard { +pub(crate) struct SeqLockWriteGuard { /// The parent lock. lock: &'static SeqLock, @@ -75,7 +75,7 @@ pub struct SeqLockWriteGuard { impl SeqLockWriteGuard { /// Releases the lock without incrementing the stamp. #[inline] - pub fn abort(self) { + pub(crate) fn abort(self) { self.lock.state.store(self.state, Ordering::Release); // We specifically don't want to call drop(), since that's diff --git a/third_party/rust/crossbeam-utils/src/atomic/seq_lock_wide.rs b/third_party/rust/crossbeam-utils/src/atomic/seq_lock_wide.rs index 871a93d28b57018f22480b81668a8c13d794cab3..ef5d94a45413dce5c36f3533403601ca44ef1a70 100644 --- a/third_party/rust/crossbeam-utils/src/atomic/seq_lock_wide.rs +++ b/third_party/rust/crossbeam-utils/src/atomic/seq_lock_wide.rs @@ -7,7 +7,7 @@ use crate::Backoff; /// /// The state is represented as two `AtomicUsize`: `state_hi` for high bits and `state_lo` for low /// bits. -pub struct SeqLock { +pub(crate) struct SeqLock { /// The high bits of the current state of the lock. state_hi: AtomicUsize, @@ -19,7 +19,7 @@ pub struct SeqLock { } impl SeqLock { - pub const fn new() -> Self { + pub(crate) const fn new() -> Self { Self { state_hi: AtomicUsize::new(0), state_lo: AtomicUsize::new(0), @@ -30,7 +30,7 @@ impl SeqLock { /// /// This method should be called before optimistic reads. #[inline] - pub fn optimistic_read(&self) -> Option<(usize, usize)> { + pub(crate) fn optimistic_read(&self) -> Option<(usize, usize)> { // The acquire loads from `state_hi` and `state_lo` synchronize with the release stores in // `SeqLockWriteGuard::drop`. // @@ -51,7 +51,7 @@ impl SeqLock { /// This method should be called after optimistic reads to check whether they are valid. The /// argument `stamp` should correspond to the one returned by method `optimistic_read`. #[inline] - pub fn validate_read(&self, stamp: (usize, usize)) -> bool { + pub(crate) fn validate_read(&self, stamp: (usize, usize)) -> bool { // Thanks to the fence, if we're noticing any modification to the data at the critical // section of `(a, b)`, then the critical section's write of 1 to state_lo should be // visible. @@ -76,7 +76,7 @@ impl SeqLock { /// Grabs the lock for writing. #[inline] - pub fn write(&'static self) -> SeqLockWriteGuard { + pub(crate) fn write(&'static self) -> SeqLockWriteGuard { let backoff = Backoff::new(); loop { let previous = self.state_lo.swap(1, Ordering::Acquire); @@ -98,7 +98,7 @@ impl SeqLock { } /// An RAII guard that releases the lock and increments the stamp when dropped. -pub struct SeqLockWriteGuard { +pub(crate) struct SeqLockWriteGuard { /// The parent lock. lock: &'static SeqLock, @@ -109,7 +109,7 @@ pub struct SeqLockWriteGuard { impl SeqLockWriteGuard { /// Releases the lock without incrementing the stamp. #[inline] - pub fn abort(self) { + pub(crate) fn abort(self) { self.lock.state_lo.store(self.state_lo, Ordering::Release); mem::forget(self); } diff --git a/third_party/rust/crossbeam-utils/src/backoff.rs b/third_party/rust/crossbeam-utils/src/backoff.rs index 2391dd1cead4a76f1a21d1bcca1da52861b5e13f..1012f06b238a9f25fabfec6d949e6cb0ed0cd6ed 100644 --- a/third_party/rust/crossbeam-utils/src/backoff.rs +++ b/third_party/rust/crossbeam-utils/src/backoff.rs @@ -1,6 +1,6 @@ +use crate::primitive::sync::atomic; use core::cell::Cell; use core::fmt; -use core::sync::atomic; const SPIN_LIMIT: u32 = 6; const YIELD_LIMIT: u32 = 10; @@ -27,7 +27,7 @@ const YIELD_LIMIT: u32 = 10; /// let backoff = Backoff::new(); /// loop { /// let val = a.load(SeqCst); -/// if a.compare_and_swap(val, val.wrapping_mul(b), SeqCst) == val { +/// if a.compare_exchange(val, val.wrapping_mul(b), SeqCst, SeqCst).is_ok() { /// return val; /// } /// backoff.spin(); @@ -131,7 +131,7 @@ impl Backoff { /// let backoff = Backoff::new(); /// loop { /// let val = a.load(SeqCst); - /// if a.compare_and_swap(val, val.wrapping_mul(b), SeqCst) == val { + /// if a.compare_exchange(val, val.wrapping_mul(b), SeqCst, SeqCst).is_ok() { /// return val; /// } /// backoff.spin(); @@ -145,6 +145,9 @@ impl Backoff { #[inline] pub fn spin(&self) { for _ in 0..1 << self.step.get().min(SPIN_LIMIT) { + // TODO(taiki-e): once we bump the minimum required Rust version to 1.49+, + // use [`core::hint::spin_loop`] instead. + #[allow(deprecated)] atomic::spin_loop_hint(); } @@ -205,11 +208,17 @@ impl Backoff { pub fn snooze(&self) { if self.step.get() <= SPIN_LIMIT { for _ in 0..1 << self.step.get() { + // TODO(taiki-e): once we bump the minimum required Rust version to 1.49+, + // use [`core::hint::spin_loop`] instead. + #[allow(deprecated)] atomic::spin_loop_hint(); } } else { #[cfg(not(feature = "std"))] for _ in 0..1 << self.step.get() { + // TODO(taiki-e): once we bump the minimum required Rust version to 1.49+, + // use [`core::hint::spin_loop`] instead. + #[allow(deprecated)] atomic::spin_loop_hint(); } diff --git a/third_party/rust/crossbeam-utils/src/cache_padded.rs b/third_party/rust/crossbeam-utils/src/cache_padded.rs index 62c686b7e3909f06d2ee0aabbd5fec8c48072b5d..822e831d16281f7f97e895c19e713911381c1c75 100644 --- a/third_party/rust/crossbeam-utils/src/cache_padded.rs +++ b/third_party/rust/crossbeam-utils/src/cache_padded.rs @@ -13,7 +13,9 @@ use core::ops::{Deref, DerefMut}; /// /// Cache lines are assumed to be N bytes long, depending on the architecture: /// -/// * On x86-64 and aarch64, N = 128. +/// * On x86-64, aarch64, and powerpc64, N = 128. +/// * On arm, mips, mips64, and riscv64, N = 32. +/// * On s390x, N = 256. /// * On all others, N = 64. /// /// Note that N is just a reasonable guess and is not guaranteed to match the actual cache line @@ -64,13 +66,63 @@ use core::ops::{Deref, DerefMut}; // - https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf // - https://github.com/facebook/folly/blob/1b5288e6eea6df074758f877c849b6e73bbb9fbb/folly/lang/Align.h#L107 // -// ARM's big.LITTLE architecture has asymmetric cores and "big" cores have 128 byte cache line size +// ARM's big.LITTLE architecture has asymmetric cores and "big" cores have 128-byte cache line size. +// // Sources: // - https://www.mono-project.com/news/2016/09/12/arm64-icache/ // -#[cfg_attr(any(target_arch = "x86_64", target_arch = "aarch64"), repr(align(128)))] +// powerpc64 has 128-byte cache line size. +// +// Sources: +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_ppc64x.go#L9 +#[cfg_attr( + any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "powerpc64", + ), + repr(align(128)) +)] +// arm, mips, mips64, and riscv64 have 32-byte cache line size. +// +// Sources: +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_arm.go#L7 +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips.go#L7 +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7 +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9 +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_riscv64.go#L7 +#[cfg_attr( + any( + target_arch = "arm", + target_arch = "mips", + target_arch = "mips64", + target_arch = "riscv64", + ), + repr(align(32)) +)] +// s390x has 256-byte cache line size. +// +// Sources: +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_s390x.go#L7 +#[cfg_attr(target_arch = "s390x", repr(align(256)))] +// x86 and wasm have 64-byte cache line size. +// +// Sources: +// - https://github.com/golang/go/blob/dda2991c2ea0c5914714469c4defc2562a907230/src/internal/cpu/cpu_x86.go#L9 +// - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_wasm.go#L7 +// +// All others are assumed to have 64-byte cache line size. #[cfg_attr( - not(any(target_arch = "x86_64", target_arch = "aarch64")), + not(any( + target_arch = "x86_64", + target_arch = "aarch64", + target_arch = "powerpc64", + target_arch = "arm", + target_arch = "mips", + target_arch = "mips64", + target_arch = "riscv64", + target_arch = "s390x", + )), repr(align(64)) )] pub struct CachePadded<T> { diff --git a/third_party/rust/crossbeam-utils/src/lib.rs b/third_party/rust/crossbeam-utils/src/lib.rs index f2bd460b9d30d63d7796eadc6fd45fb6c9dabee8..191c5a17d15cdfac4f218ab7b4db70ec71f545fd 100644 --- a/third_party/rust/crossbeam-utils/src/lib.rs +++ b/third_party/rust/crossbeam-utils/src/lib.rs @@ -31,13 +31,59 @@ allow(dead_code, unused_assignments, unused_variables) ) ))] -#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms)] +#![warn( + missing_docs, + missing_debug_implementations, + rust_2018_idioms, + unreachable_pub +)] #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))] -// matches! requires Rust 1.42 -#![allow(clippy::match_like_matches_macro)] -#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))] +#[cfg(crossbeam_loom)] +#[allow(unused_imports)] +mod primitive { + pub(crate) mod sync { + pub(crate) mod atomic { + pub(crate) use loom::sync::atomic::spin_loop_hint; + pub(crate) use loom::sync::atomic::{ + AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicIsize, AtomicU16, + AtomicU32, AtomicU64, AtomicU8, AtomicUsize, + }; + + // FIXME: loom does not support compiler_fence at the moment. + // https://github.com/tokio-rs/loom/issues/117 + // we use fence as a stand-in for compiler_fence for the time being. + // this may miss some races since fence is stronger than compiler_fence, + // but it's the best we can do for the time being. + pub(crate) use loom::sync::atomic::fence as compiler_fence; + } + pub(crate) use loom::sync::{Arc, Condvar, Mutex}; + } +} +#[cfg(not(crossbeam_loom))] +#[allow(unused_imports)] +mod primitive { + pub(crate) mod sync { + pub(crate) mod atomic { + pub(crate) use core::sync::atomic::compiler_fence; + // TODO(taiki-e): once we bump the minimum required Rust version to 1.49+, + // use [`core::hint::spin_loop`] instead. + #[allow(deprecated)] + pub(crate) use core::sync::atomic::spin_loop_hint; + #[cfg(not(crossbeam_no_atomic))] + pub(crate) use core::sync::atomic::{ + AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, + AtomicU8, AtomicUsize, + }; + #[cfg(not(crossbeam_no_atomic_64))] + pub(crate) use core::sync::atomic::{AtomicI64, AtomicU64}; + } + + #[cfg(feature = "std")] + pub(crate) use std::sync::{Arc, Condvar, Mutex}; + } +} + pub mod atomic; mod cache_padded; @@ -51,6 +97,8 @@ use cfg_if::cfg_if; cfg_if! { if #[cfg(feature = "std")] { pub mod sync; + + #[cfg(not(crossbeam_loom))] pub mod thread; } } diff --git a/third_party/rust/crossbeam-utils/src/sync/mod.rs b/third_party/rust/crossbeam-utils/src/sync/mod.rs index fd400d70e7ca0266e5e30c1f8975506d1b1112e7..eeb740c2cd0402e19821f7557317d7a5acb42e12 100644 --- a/third_party/rust/crossbeam-utils/src/sync/mod.rs +++ b/third_party/rust/crossbeam-utils/src/sync/mod.rs @@ -5,9 +5,11 @@ //! * [`WaitGroup`], for synchronizing the beginning or end of some computation. mod parker; +#[cfg(not(crossbeam_loom))] mod sharded_lock; mod wait_group; pub use self::parker::{Parker, Unparker}; +#[cfg(not(crossbeam_loom))] pub use self::sharded_lock::{ShardedLock, ShardedLockReadGuard, ShardedLockWriteGuard}; pub use self::wait_group::WaitGroup; diff --git a/third_party/rust/crossbeam-utils/src/sync/parker.rs b/third_party/rust/crossbeam-utils/src/sync/parker.rs index fc13d2e967df8dd85ecc3ec5778b991715796599..aefa5152738f3a469138ab6966c5fdbb05e8a004 100644 --- a/third_party/rust/crossbeam-utils/src/sync/parker.rs +++ b/third_party/rust/crossbeam-utils/src/sync/parker.rs @@ -1,20 +1,19 @@ +use crate::primitive::sync::atomic::AtomicUsize; +use crate::primitive::sync::{Arc, Condvar, Mutex}; +use core::sync::atomic::Ordering::SeqCst; use std::fmt; use std::marker::PhantomData; -use std::sync::atomic::AtomicUsize; -use std::sync::atomic::Ordering::SeqCst; -use std::sync::{Arc, Condvar, Mutex}; -use std::time::Duration; +use std::time::{Duration, Instant}; /// A thread parking primitive. /// /// Conceptually, each `Parker` has an associated token which is initially not present: /// /// * The [`park`] method blocks the current thread unless or until the token is available, at -/// which point it automatically consumes the token. It may also return *spuriously*, without -/// consuming the token. +/// which point it automatically consumes the token. /// -/// * The [`park_timeout`] method works the same as [`park`], but blocks for a specified maximum -/// time. +/// * The [`park_timeout`] and [`park_deadline`] methods work the same as [`park`], but block for +/// a specified maximum time. /// /// * The [`unpark`] method atomically makes the token available if it wasn't already. Because the /// token is initially absent, [`unpark`] followed by [`park`] will result in the second call @@ -43,13 +42,13 @@ use std::time::Duration; /// u.unpark(); /// }); /// -/// // Wakes up when `u.unpark()` provides the token, but may also wake up -/// // spuriously before that without consuming the token. +/// // Wakes up when `u.unpark()` provides the token. /// p.park(); /// ``` /// /// [`park`]: Parker::park /// [`park_timeout`]: Parker::park_timeout +/// [`park_deadline`]: Parker::park_deadline /// [`unpark`]: Unparker::unpark pub struct Parker { unparker: Unparker, @@ -90,9 +89,6 @@ impl Parker { /// Blocks the current thread until the token is made available. /// - /// A call to `park` may wake up spuriously without consuming the token, and callers should be - /// prepared for this possibility. - /// /// # Examples /// /// ``` @@ -113,9 +109,6 @@ impl Parker { /// Blocks the current thread until the token is made available, but only for a limited time. /// - /// A call to `park_timeout` may wake up spuriously without consuming the token, and callers - /// should be prepared for this possibility. - /// /// # Examples /// /// ``` @@ -128,7 +121,25 @@ impl Parker { /// p.park_timeout(Duration::from_millis(500)); /// ``` pub fn park_timeout(&self, timeout: Duration) { - self.unparker.inner.park(Some(timeout)); + self.park_deadline(Instant::now() + timeout) + } + + /// Blocks the current thread until the token is made available, or until a certain deadline. + /// + /// # Examples + /// + /// ``` + /// use std::time::{Duration, Instant}; + /// use crossbeam_utils::sync::Parker; + /// + /// let p = Parker::new(); + /// let deadline = Instant::now() + Duration::from_millis(500); + /// + /// // Waits for the token to become available, but will not wait longer than 500 ms. + /// p.park_deadline(deadline); + /// ``` + pub fn park_deadline(&self, deadline: Instant) { + self.unparker.inner.park(Some(deadline)) } /// Returns a reference to an associated [`Unparker`]. @@ -227,8 +238,7 @@ impl Unparker { /// u.unpark(); /// }); /// - /// // Wakes up when `u.unpark()` provides the token, but may also wake up - /// // spuriously before that without consuming the token. + /// // Wakes up when `u.unpark()` provides the token. /// p.park(); /// ``` /// @@ -302,7 +312,7 @@ struct Inner { } impl Inner { - fn park(&self, timeout: Option<Duration>) { + fn park(&self, deadline: Option<Instant>) { // If we were previously notified then we consume this notification and return quickly. if self .state @@ -313,8 +323,8 @@ impl Inner { } // If the timeout is zero, then there is no need to actually block. - if let Some(ref dur) = timeout { - if *dur == Duration::from_millis(0) { + if let Some(deadline) = deadline { + if deadline <= Instant::now() { return; } } @@ -338,40 +348,42 @@ impl Inner { Err(n) => panic!("inconsistent park_timeout state: {}", n), } - match timeout { - None => { - loop { - // Block the current thread on the conditional variable. - m = self.cvar.wait(m).unwrap(); - - if self - .state - .compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst) - .is_ok() - { - // got a notification - return; + loop { + // Block the current thread on the conditional variable. + m = match deadline { + None => self.cvar.wait(m).unwrap(), + Some(deadline) => { + let now = Instant::now(); + if now < deadline { + // We could check for a timeout here, in the return value of wait_timeout, + // but in the case that a timeout and an unpark arrive simultaneously, we + // prefer to report the former. + self.cvar.wait_timeout(m, deadline - now).unwrap().0 + } else { + // We've timed out; swap out the state back to empty on our way out + match self.state.swap(EMPTY, SeqCst) { + NOTIFIED | PARKED => return, + n => panic!("inconsistent park_timeout state: {}", n), + }; } - - // spurious wakeup, go back to sleep } - } - Some(timeout) => { - // Wait with a timeout, and if we spuriously wake up or otherwise wake up from a - // notification we just want to unconditionally set `state` back to `EMPTY`, either - // consuming a notification or un-flagging ourselves as parked. - let (_m, _result) = self.cvar.wait_timeout(m, timeout).unwrap(); + }; - match self.state.swap(EMPTY, SeqCst) { - NOTIFIED => {} // got a notification - PARKED => {} // no notification - n => panic!("inconsistent park_timeout state: {}", n), - } + if self + .state + .compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst) + .is_ok() + { + // got a notification + return; } + + // Spurious wakeup, go back to sleep. Alternatively, if we timed out, it will be caught + // in the branch above, when we discover the deadline is in the past } } - pub fn unpark(&self) { + pub(crate) fn unpark(&self) { // To ensure the unparked thread will observe any writes we made before this call, we must // perform a release operation that `park` can synchronize with. To do that we must write // `NOTIFIED` even if `state` is already `NOTIFIED`. That is why this must be a swap rather diff --git a/third_party/rust/crossbeam-utils/src/sync/wait_group.rs b/third_party/rust/crossbeam-utils/src/sync/wait_group.rs index cd7af12a369e2db8e6b4a0616731467068ab9bba..4206ee42b7b370bf1645888a819a1c4a7ac152a6 100644 --- a/third_party/rust/crossbeam-utils/src/sync/wait_group.rs +++ b/third_party/rust/crossbeam-utils/src/sync/wait_group.rs @@ -1,8 +1,8 @@ // Necessary for using `Mutex<usize>` for conditional variables #![allow(clippy::mutex_atomic)] +use crate::primitive::sync::{Arc, Condvar, Mutex}; use std::fmt; -use std::sync::{Arc, Condvar, Mutex}; /// Enables threads to synchronize the beginning or end of some computation. /// diff --git a/third_party/rust/crossbeam-utils/src/thread.rs b/third_party/rust/crossbeam-utils/src/thread.rs index ab91be72d19c165be04c2ef82f427c6a265bd251..c57d076fbe2148a62724b1ee92772ffa05ffc607 100644 --- a/third_party/rust/crossbeam-utils/src/thread.rs +++ b/third_party/rust/crossbeam-utils/src/thread.rs @@ -110,8 +110,6 @@ //! }); //! }).unwrap(); //! ``` -//! -//! [`std::thread::spawn`]: std::thread::spawn use std::fmt; use std::io; @@ -572,7 +570,6 @@ cfg_if! { } } - #[cfg(windows)] impl<T> IntoRawHandle for ScopedJoinHandle<'_, T> { fn into_raw_handle(self) -> RawHandle { self.as_raw_handle() diff --git a/third_party/rust/crossbeam-utils/tests/atomic_cell.rs b/third_party/rust/crossbeam-utils/tests/atomic_cell.rs index 3d91d81d69589ea3770b42cbc9002ed51494ba59..28208ee7698c5e7d9b00d1c69e78cb375c8831d3 100644 --- a/third_party/rust/crossbeam-utils/tests/atomic_cell.rs +++ b/third_party/rust/crossbeam-utils/tests/atomic_cell.rs @@ -1,3 +1,4 @@ +use std::mem; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::SeqCst; @@ -8,18 +9,47 @@ fn is_lock_free() { struct UsizeWrap(usize); struct U8Wrap(bool); struct I16Wrap(i16); - - assert_eq!(AtomicCell::<usize>::is_lock_free(), true); - assert_eq!(AtomicCell::<isize>::is_lock_free(), true); - assert_eq!(AtomicCell::<UsizeWrap>::is_lock_free(), true); - - assert_eq!(AtomicCell::<u8>::is_lock_free(), cfg!(has_atomic_u8)); - assert_eq!(AtomicCell::<bool>::is_lock_free(), cfg!(has_atomic_u8)); - assert_eq!(AtomicCell::<U8Wrap>::is_lock_free(), cfg!(has_atomic_u8)); - - assert_eq!(AtomicCell::<I16Wrap>::is_lock_free(), cfg!(has_atomic_u16)); - - assert_eq!(AtomicCell::<u128>::is_lock_free(), cfg!(has_atomic_u128)); + #[repr(align(8))] + struct U64Align8(u64); + + assert!(AtomicCell::<usize>::is_lock_free()); + assert!(AtomicCell::<isize>::is_lock_free()); + assert!(AtomicCell::<UsizeWrap>::is_lock_free()); + + assert!(AtomicCell::<()>::is_lock_free()); + + assert!(AtomicCell::<u8>::is_lock_free()); + assert!(AtomicCell::<i8>::is_lock_free()); + assert!(AtomicCell::<bool>::is_lock_free()); + assert!(AtomicCell::<U8Wrap>::is_lock_free()); + + assert!(AtomicCell::<u16>::is_lock_free()); + assert!(AtomicCell::<i16>::is_lock_free()); + assert!(AtomicCell::<I16Wrap>::is_lock_free()); + + assert!(AtomicCell::<u32>::is_lock_free()); + assert!(AtomicCell::<i32>::is_lock_free()); + + // Sizes of both types must be equal, and the alignment of `u64` must be greater or equal than + // that of `AtomicU64`. In i686-unknown-linux-gnu, the alignment of `u64` is `4` and alignment + // of `AtomicU64` is `8`, so `AtomicCell<u64>` is not lock-free. + assert_eq!( + AtomicCell::<u64>::is_lock_free(), + cfg!(not(crossbeam_no_atomic_64)) + && cfg!(any( + target_pointer_width = "64", + target_pointer_width = "128" + )) + ); + assert_eq!(mem::size_of::<U64Align8>(), 8); + assert_eq!(mem::align_of::<U64Align8>(), 8); + assert_eq!( + AtomicCell::<U64Align8>::is_lock_free(), + cfg!(not(crossbeam_no_atomic_64)) + ); + + // AtomicU128 is unstable + assert!(!AtomicCell::<u128>::is_lock_free()); } #[test] diff --git a/third_party/rust/crossbeam-utils/tests/cache_padded.rs b/third_party/rust/crossbeam-utils/tests/cache_padded.rs index be90cbe91da1c0e568c39d1c384263cc5355072e..86e9a7709c67154182853ad4513457b56b0c6fb1 100644 --- a/third_party/rust/crossbeam-utils/tests/cache_padded.rs +++ b/third_party/rust/crossbeam-utils/tests/cache_padded.rs @@ -27,7 +27,9 @@ fn distance() { let arr = [CachePadded::new(17u8), CachePadded::new(37u8)]; let a = &*arr[0] as *const u8; let b = &*arr[1] as *const u8; - assert!(unsafe { a.offset(64) } <= b); + let align = mem::align_of::<CachePadded<()>>(); + assert!(align >= 32); + assert_eq!(unsafe { a.add(align) }, b); } #[test] @@ -83,6 +85,7 @@ fn drops() { assert_eq!(count.get(), 2); } +#[allow(clippy::clone_on_copy)] // This is intentional. #[test] fn clone() { let a = CachePadded::new(17); diff --git a/third_party/rust/crossbeam-utils/tests/parker.rs b/third_party/rust/crossbeam-utils/tests/parker.rs index f657eb1cf015353257f3c0a0b32a36901e50db00..2bf9c37d491e65a3786b41236bfdbdb0c4ef588a 100644 --- a/third_party/rust/crossbeam-utils/tests/parker.rs +++ b/third_party/rust/crossbeam-utils/tests/parker.rs @@ -18,7 +18,7 @@ fn park_timeout_unpark_before() { fn park_timeout_unpark_not_called() { let p = Parker::new(); for _ in 0..10 { - p.park_timeout(Duration::from_millis(10)); + p.park_timeout(Duration::from_millis(10)) } } @@ -34,7 +34,7 @@ fn park_timeout_unpark_called_other_thread() { u.unpark(); }); - p.park_timeout(Duration::from_millis(u32::MAX as u64)); + p.park_timeout(Duration::from_millis(u32::MAX as u64)) }) .unwrap(); } diff --git a/third_party/rust/crossbeam-utils/tests/sharded_lock.rs b/third_party/rust/crossbeam-utils/tests/sharded_lock.rs index 73bd489d3c2b306c5f0b72825feb3005352b37d5..b46d64a76bf5837989036f3763eab0e318939851 100644 --- a/third_party/rust/crossbeam-utils/tests/sharded_lock.rs +++ b/third_party/rust/crossbeam-utils/tests/sharded_lock.rs @@ -138,7 +138,7 @@ fn arc() { fn arc_access_in_unwind() { let arc = Arc::new(ShardedLock::new(1)); let arc2 = arc.clone(); - let _ = thread::spawn(move || -> () { + let _ = thread::spawn(move || { struct Unwinder { i: Arc<ShardedLock<isize>>, } @@ -176,11 +176,8 @@ fn try_write() { let write_result = lock.try_write(); match write_result { Err(TryLockError::WouldBlock) => (), - Ok(_) => assert!( - false, - "try_write should not succeed while read_guard is in scope" - ), - Err(_) => assert!(false, "unexpected error"), + Ok(_) => panic!("try_write should not succeed while read_guard is in scope"), + Err(_) => panic!("unexpected error"), } drop(read_guard);