Snap for 8730993 from f85f5d224d731630716bfd9a48489056a68919dc to mainline-tzdata3-release

Change-Id: I15be08aeb5e652e2ca372538682d8984f592dde4
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 0d40a83..1d9c34d 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,5 @@
 {
   "git": {
-    "sha1": "2988f873f87d2263a7fd2b9465fb9c28f43a6490"
-  },
-  "path_in_vcs": "crossbeam-utils"
-}
\ No newline at end of file
+    "sha1": "d841a2028dc72b4e09739116f07e865db60f3690"
+  }
+}
diff --git a/Android.bp b/Android.bp
index 5f17007..1a2c24f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,4 @@
-// This file is generated by cargo2android.py --config cargo2android.json.
+// This file is generated by cargo2android.py --run --device --dependencies --tests.
 // Do not modify this file as changes will be overridden on upgrade.
 
 package {
@@ -39,37 +39,47 @@
     ],
 }
 
-rust_test {
-    name: "crossbeam-utils_test_src_lib",
-    host_supported: true,
+rust_defaults {
+    name: "crossbeam-utils_defaults",
     crate_name: "crossbeam_utils",
-    cargo_env_compat: true,
-    cargo_pkg_version: "0.8.7",
     srcs: ["src/lib.rs"],
     test_suites: ["general-tests"],
     auto_gen_config: true,
-    test_options: {
-        unit_test: true,
-    },
     edition: "2018",
     features: [
         "default",
         "lazy_static",
         "std",
     ],
+    cfgs: [
+        "has_atomic_u16",
+        "has_atomic_u32",
+        "has_atomic_u64",
+        "has_atomic_u8",
+    ],
     rustlibs: [
         "libcfg_if",
         "liblazy_static",
         "librand",
     ],
-    proc_macros: ["librustversion"],
+}
+
+rust_test_host {
+    name: "crossbeam-utils_host_test_src_lib",
+    defaults: ["crossbeam-utils_defaults"],
+    test_options: {
+        unit_test: true,
+    },
+}
+
+rust_test {
+    name: "crossbeam-utils_device_test_src_lib",
+    defaults: ["crossbeam-utils_defaults"],
 }
 
 rust_defaults {
-    name: "crossbeam-utils_test_defaults",
+    name: "crossbeam-utils_defaults_crossbeam_utils",
     crate_name: "crossbeam_utils",
-    cargo_env_compat: true,
-    cargo_pkg_version: "0.8.7",
     test_suites: ["general-tests"],
     auto_gen_config: true,
     edition: "2018",
@@ -78,19 +88,23 @@
         "lazy_static",
         "std",
     ],
+    cfgs: [
+        "has_atomic_u16",
+        "has_atomic_u32",
+        "has_atomic_u64",
+        "has_atomic_u8",
+    ],
     rustlibs: [
         "libcfg_if",
         "libcrossbeam_utils",
         "liblazy_static",
         "librand",
     ],
-    proc_macros: ["librustversion"],
 }
 
-rust_test {
-    name: "crossbeam-utils_test_tests_atomic_cell",
-    defaults: ["crossbeam-utils_test_defaults"],
-    host_supported: true,
+rust_test_host {
+    name: "crossbeam-utils_host_test_tests_atomic_cell",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
     srcs: ["tests/atomic_cell.rs"],
     test_options: {
         unit_test: true,
@@ -98,9 +112,14 @@
 }
 
 rust_test {
-    name: "crossbeam-utils_test_tests_cache_padded",
-    defaults: ["crossbeam-utils_test_defaults"],
-    host_supported: true,
+    name: "crossbeam-utils_device_test_tests_atomic_cell",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
+    srcs: ["tests/atomic_cell.rs"],
+}
+
+rust_test_host {
+    name: "crossbeam-utils_host_test_tests_cache_padded",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
     srcs: ["tests/cache_padded.rs"],
     test_options: {
         unit_test: true,
@@ -108,9 +127,14 @@
 }
 
 rust_test {
-    name: "crossbeam-utils_test_tests_parker",
-    defaults: ["crossbeam-utils_test_defaults"],
-    host_supported: true,
+    name: "crossbeam-utils_device_test_tests_cache_padded",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
+    srcs: ["tests/cache_padded.rs"],
+}
+
+rust_test_host {
+    name: "crossbeam-utils_host_test_tests_parker",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
     srcs: ["tests/parker.rs"],
     test_options: {
         unit_test: true,
@@ -118,9 +142,14 @@
 }
 
 rust_test {
-    name: "crossbeam-utils_test_tests_sharded_lock",
-    defaults: ["crossbeam-utils_test_defaults"],
-    host_supported: true,
+    name: "crossbeam-utils_device_test_tests_parker",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
+    srcs: ["tests/parker.rs"],
+}
+
+rust_test_host {
+    name: "crossbeam-utils_host_test_tests_sharded_lock",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
     srcs: ["tests/sharded_lock.rs"],
     test_options: {
         unit_test: true,
@@ -128,9 +157,14 @@
 }
 
 rust_test {
-    name: "crossbeam-utils_test_tests_thread",
-    defaults: ["crossbeam-utils_test_defaults"],
-    host_supported: true,
+    name: "crossbeam-utils_device_test_tests_sharded_lock",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
+    srcs: ["tests/sharded_lock.rs"],
+}
+
+rust_test_host {
+    name: "crossbeam-utils_host_test_tests_thread",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
     srcs: ["tests/thread.rs"],
     test_options: {
         unit_test: true,
@@ -138,21 +172,30 @@
 }
 
 rust_test {
-    name: "crossbeam-utils_test_tests_wait_group",
-    defaults: ["crossbeam-utils_test_defaults"],
-    host_supported: true,
+    name: "crossbeam-utils_device_test_tests_thread",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
+    srcs: ["tests/thread.rs"],
+}
+
+rust_test_host {
+    name: "crossbeam-utils_host_test_tests_wait_group",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
     srcs: ["tests/wait_group.rs"],
     test_options: {
         unit_test: true,
     },
 }
 
+rust_test {
+    name: "crossbeam-utils_device_test_tests_wait_group",
+    defaults: ["crossbeam-utils_defaults_crossbeam_utils"],
+    srcs: ["tests/wait_group.rs"],
+}
+
 rust_library {
     name: "libcrossbeam_utils",
     host_supported: true,
     crate_name: "crossbeam_utils",
-    cargo_env_compat: true,
-    cargo_pkg_version: "0.8.7",
     srcs: ["src/lib.rs"],
     edition: "2018",
     features: [
@@ -160,12 +203,25 @@
         "lazy_static",
         "std",
     ],
+    cfgs: [
+        "has_atomic_u16",
+        "has_atomic_u32",
+        "has_atomic_u64",
+        "has_atomic_u8",
+    ],
     rustlibs: [
         "libcfg_if",
         "liblazy_static",
     ],
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.virt",
-    ],
 }
+
+// dependent_library ["feature_list"]
+//   autocfg-1.0.1
+//   cfg-if-1.0.0
+//   getrandom-0.2.2 "std"
+//   lazy_static-1.4.0
+//   libc-0.2.93
+//   ppv-lite86-0.2.10 "simd,std"
+//   rand-0.8.3 "alloc,default,getrandom,libc,rand_chacha,rand_hc,std,std_rng"
+//   rand_chacha-0.3.0 "std"
+//   rand_core-0.6.2 "alloc,getrandom,std"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 98088c5..c4a92bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,23 +1,3 @@
-# Version 0.8.7
-
-- Add `AtomicCell<{i*,u*}>::{fetch_max,fetch_min}`. (#785)
-- Add `AtomicCell<{i*,u*,bool}>::fetch_nand`. (#785)
-- Fix unsoundness of `AtomicCell<{i,u}64>` arithmetics on 32-bit targets that support `Atomic{I,U}64` (#781)
-
-# Version 0.8.6
-
-- Re-add `AtomicCell<{i,u}64>::{fetch_add,fetch_sub,fetch_and,fetch_or,fetch_xor}` that were accidentally removed in 0.8.0 on targets that do not support `Atomic{I,U}64`. (#767)
-- Re-add `AtomicCell<{i,u}128>::{fetch_add,fetch_sub,fetch_and,fetch_or,fetch_xor}` that were accidentally removed in 0.8.0. (#767)
-
-# 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)
diff --git a/Cargo.toml b/Cargo.toml
index 10d3240..a7d694c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,52 +3,40 @@
 # When uploading crates to the registry Cargo will automatically
 # "normalize" Cargo.toml files for maximal compatibility
 # with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
+# to registry (e.g., crates.io) dependencies
 #
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
 
 [package]
 edition = "2018"
-rust-version = "1.36"
 name = "crossbeam-utils"
-version = "0.8.7"
+version = "0.8.3"
+authors = ["The Crossbeam Project Developers"]
 description = "Utilities for concurrent programming"
 homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils"
-keywords = [
-    "scoped",
-    "thread",
-    "atomic",
-    "cache",
-]
-categories = [
-    "algorithms",
-    "concurrency",
-    "data-structures",
-    "no-std",
-]
+documentation = "https://docs.rs/crossbeam-utils"
+keywords = ["scoped", "thread", "atomic", "cache"]
+categories = ["algorithms", "concurrency", "data-structures", "no-std"]
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/crossbeam-rs/crossbeam"
-
 [dependencies.cfg-if]
 version = "1"
 
 [dependencies.lazy_static]
 version = "1.4.0"
 optional = true
-
 [dev-dependencies.rand]
 version = "0.8"
-
-[dev-dependencies.rustversion]
-version = "1"
+[build-dependencies.autocfg]
+version = "1.0.0"
 
 [features]
 default = ["std"]
 nightly = []
 std = ["lazy_static"]
-
 [target."cfg(crossbeam_loom)".dependencies.loom]
-version = "0.5"
+version = "0.4"
 optional = true
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 73508a9..30697d2 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -4,12 +4,13 @@
 # - Update CHANGELOG.md
 # - Update README.md
 # - Create "crossbeam-utils-X.Y.Z" git tag
-version = "0.8.7"
+version = "0.8.3"
+authors = ["The Crossbeam Project Developers"]
 edition = "2018"
-rust-version = "1.36"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/crossbeam-rs/crossbeam"
 homepage = "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils"
+documentation = "https://docs.rs/crossbeam-utils"
 description = "Utilities for concurrent programming"
 keywords = ["scoped", "thread", "atomic", "cache"]
 categories = ["algorithms", "concurrency", "data-structures", "no-std"]
@@ -21,13 +22,10 @@
 # This is enabled by default.
 std = ["lazy_static"]
 
-# These features are no longer used.
-# TODO: remove in the next major version.
 # Enable to use of unstable functionality.
 # This is disabled by default and requires recent nightly compiler.
-#
-# NOTE: This feature is outside of the normal semver guarantees and minor or
-# patch versions of crossbeam may make breaking changes to them at any time.
+# Note that this is outside of the normal semver guarantees and minor versions
+# of crossbeam may make breaking changes to them at any time.
 nightly = []
 
 [dependencies]
@@ -36,11 +34,13 @@
 
 # Enable the use of loom for concurrency testing.
 #
-# NOTE: This feature is outside of the normal semver guarantees and minor or
-# patch versions of crossbeam may make breaking changes to them at any time.
+# This configuration option is outside of the normal semver guarantees: minor
+# versions of crossbeam may make breaking changes to it at any time.
 [target.'cfg(crossbeam_loom)'.dependencies]
-loom = { version = "0.5", optional = true }
+loom = { version = "0.4", optional = true }
+
+[build-dependencies]
+autocfg = "1.0.0"
 
 [dev-dependencies]
 rand = "0.8"
-rustversion = "1"
diff --git a/METADATA b/METADATA
index 2c55b77..e66f8d0 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/crossbeam-utils/crossbeam-utils-0.8.7.crate"
+    value: "https://static.crates.io/crates/crossbeam-utils/crossbeam-utils-0.8.3.crate"
   }
-  version: "0.8.7"
+  version: "0.8.3"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2022
-    month: 3
+    year: 2021
+    month: 4
     day: 1
   }
 }
diff --git a/README.md b/README.md
index 6e9a8e4..fd0943b 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
 https://docs.rs/crossbeam-utils)
 [![Rust 1.36+](https://img.shields.io/badge/rust-1.36+-lightgray.svg)](
 https://www.rust-lang.org)
-[![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.com/invite/JXYwgWZ)
+[![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.gg/BBYwKq)
 
 This crate provides miscellaneous tools for concurrent programming:
 
diff --git a/TEST_MAPPING b/TEST_MAPPING
index eb8da39..a68b776 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,78 +1,32 @@
 // Generated by update_crate_tests.py for tests that depend on this crate.
 {
-  "imports": [
-    {
-      "path": "external/rust/crates/base64"
-    },
-    {
-      "path": "external/rust/crates/crossbeam-deque"
-    },
-    {
-      "path": "external/rust/crates/crossbeam-epoch"
-    },
-    {
-      "path": "external/rust/crates/crossbeam-queue"
-    },
-    {
-      "path": "external/rust/crates/once_cell"
-    },
-    {
-      "path": "external/rust/crates/tinytemplate"
-    },
-    {
-      "path": "external/rust/crates/tinyvec"
-    },
-    {
-      "path": "external/rust/crates/unicode-xid"
-    },
-    {
-      "path": "external/rust/crates/vulkano"
-    }
-  ],
   "presubmit": [
     {
-      "name": "crossbeam-utils_test_src_lib"
+      "name": "crossbeam-epoch_device_test_src_lib"
     },
     {
-      "name": "crossbeam-utils_test_tests_atomic_cell"
+      "name": "crossbeam-epoch_device_test_tests_loom"
     },
     {
-      "name": "crossbeam-utils_test_tests_cache_padded"
+      "name": "crossbeam-utils_device_test_src_lib"
     },
     {
-      "name": "crossbeam-utils_test_tests_parker"
+      "name": "crossbeam-utils_device_test_tests_atomic_cell"
     },
     {
-      "name": "crossbeam-utils_test_tests_sharded_lock"
+      "name": "crossbeam-utils_device_test_tests_cache_padded"
     },
     {
-      "name": "crossbeam-utils_test_tests_thread"
+      "name": "crossbeam-utils_device_test_tests_parker"
     },
     {
-      "name": "crossbeam-utils_test_tests_wait_group"
-    }
-  ],
-  "presubmit-rust": [
-    {
-      "name": "crossbeam-utils_test_src_lib"
+      "name": "crossbeam-utils_device_test_tests_sharded_lock"
     },
     {
-      "name": "crossbeam-utils_test_tests_atomic_cell"
+      "name": "crossbeam-utils_device_test_tests_thread"
     },
     {
-      "name": "crossbeam-utils_test_tests_cache_padded"
-    },
-    {
-      "name": "crossbeam-utils_test_tests_parker"
-    },
-    {
-      "name": "crossbeam-utils_test_tests_sharded_lock"
-    },
-    {
-      "name": "crossbeam-utils_test_tests_thread"
-    },
-    {
-      "name": "crossbeam-utils_test_tests_wait_group"
+      "name": "crossbeam-utils_device_test_tests_wait_group"
     }
   ]
 }
diff --git a/build.rs b/build.rs
index a7557fd..3e51021 100644
--- a/build.rs
+++ b/build.rs
@@ -1,61 +1,23 @@
-// The rustc-cfg listed below are considered public API, but it is *unstable*
-// and outside of the normal semver guarantees:
-//
-// - `crossbeam_no_atomic_cas`
-//      Assume the target does *not* support atomic CAS operations.
-//      This is usually detected automatically by the build script, but you may
-//      need to enable it manually when building for custom targets or using
-//      non-cargo build systems that don't run the build script.
-//
-// - `crossbeam_no_atomic`
-//      Assume the target does *not* support any atomic operations.
-//      This is usually detected automatically by the build script, but you may
-//      need to enable it manually when building for custom targets or using
-//      non-cargo build systems that don't run the build script.
-//
-// - `crossbeam_no_atomic_64`
-//      Assume the target does *not* support AtomicU64/AtomicI64.
-//      This is usually detected automatically by the build script, but you may
-//      need to enable it manually when building for custom targets or using
-//      non-cargo build systems that don't run the build script.
-//
-// With the exceptions mentioned above, the rustc-cfg emitted by the build
-// script are *not* public API.
+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 target = match env::var("TARGET") {
-        Ok(target) => target,
+    let cfg = match AutoCfg::new() {
+        Ok(cfg) => cfg,
         Err(e) => {
             println!(
-                "cargo:warning={}: unable to get TARGET environment variable: {}",
-                env!("CARGO_PKG_NAME"),
+                "cargo:warning=crossbeam-utils: unable to determine rustc version: {}",
                 e
             );
             return;
         }
     };
 
-    // 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` or `"max-atomic-width" == 128`.
-    }
-
-    println!("cargo:rerun-if-changed=no_atomic.rs");
+    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/cargo2android.json b/cargo2android.json
deleted file mode 100644
index 6e516e0..0000000
--- a/cargo2android.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "apex-available": [
-    "//apex_available:platform",
-    "com.android.virt"
-  ],
-  "device": true,
-  "run": true,
-  "tests": true
-}
\ No newline at end of file
diff --git a/no_atomic.rs b/no_atomic.rs
deleted file mode 100644
index 90ac60a..0000000
--- a/no_atomic.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-// This file is @generated by no_atomic.sh.
-// It is not intended for manual editing.
-
-const NO_ATOMIC_CAS: &[&str] = &[
-    "avr-unknown-gnu-atmega328",
-    "bpfeb-unknown-none",
-    "bpfel-unknown-none",
-    "msp430-none-elf",
-    "riscv32i-unknown-none-elf",
-    "riscv32imc-unknown-none-elf",
-    "thumbv4t-none-eabi",
-    "thumbv6m-none-eabi",
-];
-
-#[allow(dead_code)] // Only crossbeam-utils uses this.
-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",
-    "armv6k-nintendo-3ds",
-    "armv7r-none-eabi",
-    "armv7r-none-eabihf",
-    "avr-unknown-gnu-atmega328",
-    "hexagon-unknown-linux-musl",
-    "m68k-unknown-linux-gnu",
-    "mips-unknown-linux-gnu",
-    "mips-unknown-linux-musl",
-    "mips-unknown-linux-uclibc",
-    "mipsel-sony-psp",
-    "mipsel-unknown-linux-gnu",
-    "mipsel-unknown-linux-musl",
-    "mipsel-unknown-linux-uclibc",
-    "mipsel-unknown-none",
-    "mipsisa32r6-unknown-linux-gnu",
-    "mipsisa32r6el-unknown-linux-gnu",
-    "msp430-none-elf",
-    "powerpc-unknown-freebsd",
-    "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",
-    "riscv32i-unknown-none-elf",
-    "riscv32imac-unknown-none-elf",
-    "riscv32imc-esp-espidf",
-    "riscv32imc-unknown-none-elf",
-    "thumbv4t-none-eabi",
-    "thumbv6m-none-eabi",
-    "thumbv7em-none-eabi",
-    "thumbv7em-none-eabihf",
-    "thumbv7m-none-eabi",
-    "thumbv8m.base-none-eabi",
-    "thumbv8m.main-none-eabi",
-    "thumbv8m.main-none-eabihf",
-];
-
-#[allow(dead_code)] // Only crossbeam-utils uses this.
-const NO_ATOMIC: &[&str] = &[
-    "avr-unknown-gnu-atmega328",
-    "msp430-none-elf",
-    "riscv32i-unknown-none-elf",
-    "riscv32imc-unknown-none-elf",
-];
diff --git a/patches/disable_panic_tests_on_android.patch b/patches/disable_panic_tests_on_android.patch
index 3306735..49e4758 100644
--- a/patches/disable_panic_tests_on_android.patch
+++ b/patches/disable_panic_tests_on_android.patch
@@ -1,5 +1,5 @@
---- a/tests/sharded_lock.rs
-+++ b/tests/sharded_lock.rs
+--- tests/sharded_lock.rs
++++ tests/sharded_lock.rs
 @@ -46,6 +46,8 @@ fn frob() {
  }
  
@@ -63,8 +63,8 @@
  fn test_get_mut_poison() {
      let m = Arc::new(ShardedLock::new(NonCopy(10)));
      let m2 = m.clone();
---- a/tests/thread.rs
-+++ b/tests/thread.rs
+--- tests/thread.rs
++++ tests/thread.rs
 @@ -9,6 +9,8 @@ const THREADS: usize = 10;
  const SMALL_STACK_SIZE: usize = 20;
  
diff --git a/src/atomic/atomic_cell.rs b/src/atomic/atomic_cell.rs
index 8a49464..ad094b2 100644
--- a/src/atomic/atomic_cell.rs
+++ b/src/atomic/atomic_cell.rs
@@ -1,9 +1,9 @@
 // Necessary for implementing atomic methods for `AtomicUnit`
 #![allow(clippy::unit_arg)]
+#![allow(clippy::let_unit_value)]
 
 use crate::primitive::sync::atomic::{self, AtomicBool};
 use core::cell::UnsafeCell;
-use core::cmp;
 use core::fmt;
 use core::mem;
 use core::sync::atomic::Ordering;
@@ -258,44 +258,10 @@
     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 {
-    ($t:ty, fallback, $example:tt) => {
+    ($t:ty, $example:tt) => {
         impl AtomicCell<$t> {
             /// Increments the current value by `val` and returns the previous value.
             ///
@@ -313,13 +279,10 @@
             /// ```
             #[inline]
             pub fn fetch_add(&self, val: $t) -> $t {
-                #[cfg(crossbeam_loom)]
-                {
-                    let _ = val;
-                    unimplemented!("loom does not support non-atomic atomic ops");
-                }
-                #[cfg(not(crossbeam_loom))]
-                {
+                if can_transmute::<$t, atomic::AtomicUsize>() {
+                    let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) };
+                    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()) };
                     let old = *value;
@@ -344,13 +307,10 @@
             /// ```
             #[inline]
             pub fn fetch_sub(&self, val: $t) -> $t {
-                #[cfg(crossbeam_loom)]
-                {
-                    let _ = val;
-                    unimplemented!("loom does not support non-atomic atomic ops");
-                }
-                #[cfg(not(crossbeam_loom))]
-                {
+                if can_transmute::<$t, atomic::AtomicUsize>() {
+                    let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) };
+                    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()) };
                     let old = *value;
@@ -373,13 +333,10 @@
             /// ```
             #[inline]
             pub fn fetch_and(&self, val: $t) -> $t {
-                #[cfg(crossbeam_loom)]
-                {
-                    let _ = val;
-                    unimplemented!("loom does not support non-atomic atomic ops");
-                }
-                #[cfg(not(crossbeam_loom))]
-                {
+                if can_transmute::<$t, atomic::AtomicUsize>() {
+                    let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) };
+                    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()) };
                     let old = *value;
@@ -388,35 +345,6 @@
                 }
             }
 
-            /// Applies bitwise "nand" to the current value and returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use crossbeam_utils::atomic::AtomicCell;
-            ///
-            #[doc = $example]
-            ///
-            /// assert_eq!(a.fetch_nand(3), 7);
-            /// assert_eq!(a.load(), !(7 & 3));
-            /// ```
-            #[inline]
-            pub fn fetch_nand(&self, val: $t) -> $t {
-                #[cfg(crossbeam_loom)]
-                {
-                    let _ = val;
-                    unimplemented!("loom does not support non-atomic atomic ops");
-                }
-                #[cfg(not(crossbeam_loom))]
-                {
-                    let _guard = lock(self.value.get() as usize).write();
-                    let value = unsafe { &mut *(self.value.get()) };
-                    let old = *value;
-                    *value = !(old & val);
-                    old
-                }
-            }
-
             /// Applies bitwise "or" to the current value and returns the previous value.
             ///
             /// # Examples
@@ -431,13 +359,10 @@
             /// ```
             #[inline]
             pub fn fetch_or(&self, val: $t) -> $t {
-                #[cfg(crossbeam_loom)]
-                {
-                    let _ = val;
-                    unimplemented!("loom does not support non-atomic atomic ops");
-                }
-                #[cfg(not(crossbeam_loom))]
-                {
+                if can_transmute::<$t, atomic::AtomicUsize>() {
+                    let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) };
+                    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()) };
                     let old = *value;
@@ -460,13 +385,10 @@
             /// ```
             #[inline]
             pub fn fetch_xor(&self, val: $t) -> $t {
-                #[cfg(crossbeam_loom)]
-                {
-                    let _ = val;
-                    unimplemented!("loom does not support non-atomic atomic ops");
-                }
-                #[cfg(not(crossbeam_loom))]
-                {
+                if can_transmute::<$t, atomic::AtomicUsize>() {
+                    let a = unsafe { &*(self.value.get() as *const atomic::AtomicUsize) };
+                    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()) };
                     let old = *value;
@@ -474,66 +396,6 @@
                     old
                 }
             }
-
-            /// Compares and sets the maximum of the current value and `val`,
-            /// and returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use crossbeam_utils::atomic::AtomicCell;
-            ///
-            #[doc = $example]
-            ///
-            /// assert_eq!(a.fetch_max(2), 7);
-            /// assert_eq!(a.load(), 7);
-            /// ```
-            #[inline]
-            pub fn fetch_max(&self, val: $t) -> $t {
-                #[cfg(crossbeam_loom)]
-                {
-                    let _ = val;
-                    unimplemented!("loom does not support non-atomic atomic ops");
-                }
-                #[cfg(not(crossbeam_loom))]
-                {
-                    let _guard = lock(self.value.get() as usize).write();
-                    let value = unsafe { &mut *(self.value.get()) };
-                    let old = *value;
-                    *value = cmp::max(old, val);
-                    old
-                }
-            }
-
-            /// Compares and sets the minimum of the current value and `val`,
-            /// and returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use crossbeam_utils::atomic::AtomicCell;
-            ///
-            #[doc = $example]
-            ///
-            /// assert_eq!(a.fetch_min(2), 7);
-            /// assert_eq!(a.load(), 2);
-            /// ```
-            #[inline]
-            pub fn fetch_min(&self, val: $t) -> $t {
-                #[cfg(crossbeam_loom)]
-                {
-                    let _ = val;
-                    unimplemented!("loom does not support non-atomic atomic ops");
-                }
-                #[cfg(not(crossbeam_loom))]
-                {
-                    let _guard = lock(self.value.get() as usize).write();
-                    let value = unsafe { &mut *(self.value.get()) };
-                    let old = *value;
-                    *value = cmp::min(old, val);
-                    old
-                }
-            }
         }
     };
     ($t:ty, $atomic:ty, $example:tt) => {
@@ -554,24 +416,8 @@
             /// ```
             #[inline]
             pub fn fetch_add(&self, val: $t) -> $t {
-                if can_transmute::<$t, $atomic>() {
-                    let a = unsafe { &*(self.value.get() as *const $atomic) };
-                    a.fetch_add(val, Ordering::AcqRel)
-                } else {
-                    #[cfg(crossbeam_loom)]
-                    {
-                        let _ = val;
-                        unimplemented!("loom does not support non-atomic atomic ops");
-                    }
-                    #[cfg(not(crossbeam_loom))]
-                    {
-                        let _guard = lock(self.value.get() as usize).write();
-                        let value = unsafe { &mut *(self.value.get()) };
-                        let old = *value;
-                        *value = value.wrapping_add(val);
-                        old
-                    }
-                }
+                let a = unsafe { &*(self.value.get() as *const $atomic) };
+                a.fetch_add(val, Ordering::AcqRel)
             }
 
             /// Decrements the current value by `val` and returns the previous value.
@@ -590,24 +436,8 @@
             /// ```
             #[inline]
             pub fn fetch_sub(&self, val: $t) -> $t {
-                if can_transmute::<$t, $atomic>() {
-                    let a = unsafe { &*(self.value.get() as *const $atomic) };
-                    a.fetch_sub(val, Ordering::AcqRel)
-                } else {
-                    #[cfg(crossbeam_loom)]
-                    {
-                        let _ = val;
-                        unimplemented!("loom does not support non-atomic atomic ops");
-                    }
-                    #[cfg(not(crossbeam_loom))]
-                    {
-                        let _guard = lock(self.value.get() as usize).write();
-                        let value = unsafe { &mut *(self.value.get()) };
-                        let old = *value;
-                        *value = value.wrapping_sub(val);
-                        old
-                    }
-                }
+                let a = unsafe { &*(self.value.get() as *const $atomic) };
+                a.fetch_sub(val, Ordering::AcqRel)
             }
 
             /// Applies bitwise "and" to the current value and returns the previous value.
@@ -624,58 +454,8 @@
             /// ```
             #[inline]
             pub fn fetch_and(&self, val: $t) -> $t {
-                if can_transmute::<$t, $atomic>() {
-                    let a = unsafe { &*(self.value.get() as *const $atomic) };
-                    a.fetch_and(val, Ordering::AcqRel)
-                } else {
-                    #[cfg(crossbeam_loom)]
-                    {
-                        let _ = val;
-                        unimplemented!("loom does not support non-atomic atomic ops");
-                    }
-                    #[cfg(not(crossbeam_loom))]
-                    {
-                        let _guard = lock(self.value.get() as usize).write();
-                        let value = unsafe { &mut *(self.value.get()) };
-                        let old = *value;
-                        *value &= val;
-                        old
-                    }
-                }
-            }
-
-            /// Applies bitwise "nand" to the current value and returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use crossbeam_utils::atomic::AtomicCell;
-            ///
-            #[doc = $example]
-            ///
-            /// assert_eq!(a.fetch_nand(3), 7);
-            /// assert_eq!(a.load(), !(7 & 3));
-            /// ```
-            #[inline]
-            pub fn fetch_nand(&self, val: $t) -> $t {
-                if can_transmute::<$t, $atomic>() {
-                    let a = unsafe { &*(self.value.get() as *const $atomic) };
-                    a.fetch_nand(val, Ordering::AcqRel)
-                } else {
-                    #[cfg(crossbeam_loom)]
-                    {
-                        let _ = val;
-                        unimplemented!("loom does not support non-atomic atomic ops");
-                    }
-                    #[cfg(not(crossbeam_loom))]
-                    {
-                        let _guard = lock(self.value.get() as usize).write();
-                        let value = unsafe { &mut *(self.value.get()) };
-                        let old = *value;
-                        *value = !(old & val);
-                        old
-                    }
-                }
+                let a = unsafe { &*(self.value.get() as *const $atomic) };
+                a.fetch_and(val, Ordering::AcqRel)
             }
 
             /// Applies bitwise "or" to the current value and returns the previous value.
@@ -692,24 +472,8 @@
             /// ```
             #[inline]
             pub fn fetch_or(&self, val: $t) -> $t {
-                if can_transmute::<$t, $atomic>() {
-                    let a = unsafe { &*(self.value.get() as *const $atomic) };
-                    a.fetch_or(val, Ordering::AcqRel)
-                } else {
-                    #[cfg(crossbeam_loom)]
-                    {
-                        let _ = val;
-                        unimplemented!("loom does not support non-atomic atomic ops");
-                    }
-                    #[cfg(not(crossbeam_loom))]
-                    {
-                        let _guard = lock(self.value.get() as usize).write();
-                        let value = unsafe { &mut *(self.value.get()) };
-                        let old = *value;
-                        *value |= val;
-                        old
-                    }
-                }
+                let a = unsafe { &*(self.value.get() as *const $atomic) };
+                a.fetch_or(val, Ordering::AcqRel)
             }
 
             /// Applies bitwise "xor" to the current value and returns the previous value.
@@ -726,124 +490,40 @@
             /// ```
             #[inline]
             pub fn fetch_xor(&self, val: $t) -> $t {
-                if can_transmute::<$t, $atomic>() {
-                    let a = unsafe { &*(self.value.get() as *const $atomic) };
-                    a.fetch_xor(val, Ordering::AcqRel)
-                } else {
-                    #[cfg(crossbeam_loom)]
-                    {
-                        let _ = val;
-                        unimplemented!("loom does not support non-atomic atomic ops");
-                    }
-                    #[cfg(not(crossbeam_loom))]
-                    {
-                        let _guard = lock(self.value.get() as usize).write();
-                        let value = unsafe { &mut *(self.value.get()) };
-                        let old = *value;
-                        *value ^= val;
-                        old
-                    }
-                }
-            }
-
-            /// Compares and sets the maximum of the current value and `val`,
-            /// and returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use crossbeam_utils::atomic::AtomicCell;
-            ///
-            #[doc = $example]
-            ///
-            /// assert_eq!(a.fetch_max(9), 7);
-            /// assert_eq!(a.load(), 9);
-            /// ```
-            #[inline]
-            pub fn fetch_max(&self, val: $t) -> $t {
-                if can_transmute::<$t, $atomic>() {
-                    // TODO: Atomic*::fetch_max requires Rust 1.45.
-                    self.fetch_update(|old| Some(cmp::max(old, val))).unwrap()
-                } else {
-                    #[cfg(crossbeam_loom)]
-                    {
-                        let _ = val;
-                        unimplemented!("loom does not support non-atomic atomic ops");
-                    }
-                    #[cfg(not(crossbeam_loom))]
-                    {
-                        let _guard = lock(self.value.get() as usize).write();
-                        let value = unsafe { &mut *(self.value.get()) };
-                        let old = *value;
-                        *value = cmp::max(old, val);
-                        old
-                    }
-                }
-            }
-
-            /// Compares and sets the minimum of the current value and `val`,
-            /// and returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use crossbeam_utils::atomic::AtomicCell;
-            ///
-            #[doc = $example]
-            ///
-            /// assert_eq!(a.fetch_min(2), 7);
-            /// assert_eq!(a.load(), 2);
-            /// ```
-            #[inline]
-            pub fn fetch_min(&self, val: $t) -> $t {
-                if can_transmute::<$t, $atomic>() {
-                    // TODO: Atomic*::fetch_min requires Rust 1.45.
-                    self.fetch_update(|old| Some(cmp::min(old, val))).unwrap()
-                } else {
-                    #[cfg(crossbeam_loom)]
-                    {
-                        let _ = val;
-                        unimplemented!("loom does not support non-atomic atomic ops");
-                    }
-                    #[cfg(not(crossbeam_loom))]
-                    {
-                        let _guard = lock(self.value.get() as usize).write();
-                        let value = unsafe { &mut *(self.value.get()) };
-                        let old = *value;
-                        *value = cmp::min(old, val);
-                        old
-                    }
-                }
+                let a = unsafe { &*(self.value.get() as *const $atomic) };
+                a.fetch_xor(val, Ordering::AcqRel)
             }
         }
     };
 }
 
+#[cfg(has_atomic_u8)]
 impl_arithmetic!(u8, atomic::AtomicU8, "let a = AtomicCell::new(7u8);");
+#[cfg(all(has_atomic_u8, not(crossbeam_loom)))]
 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(all(has_atomic_u16, not(crossbeam_loom)))]
 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(all(has_atomic_u32, not(crossbeam_loom)))]
 impl_arithmetic!(i32, atomic::AtomicI32, "let a = AtomicCell::new(7i32);");
-#[cfg(not(crossbeam_no_atomic_64))]
+#[cfg(has_atomic_u64)]
 impl_arithmetic!(u64, atomic::AtomicU64, "let a = AtomicCell::new(7u64);");
-#[cfg(not(crossbeam_no_atomic_64))]
+#[cfg(all(has_atomic_u64, not(crossbeam_loom)))]
 impl_arithmetic!(i64, atomic::AtomicI64, "let a = AtomicCell::new(7i64);");
-#[cfg(crossbeam_no_atomic_64)]
-impl_arithmetic!(u64, fallback, "let a = AtomicCell::new(7u64);");
-#[cfg(crossbeam_no_atomic_64)]
-impl_arithmetic!(i64, fallback, "let a = AtomicCell::new(7i64);");
-// 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!(u128, fallback, "let a = AtomicCell::new(7u128);");
-impl_arithmetic!(i128, fallback, "let a = AtomicCell::new(7i128);");
+#[cfg(all(has_atomic_u128, not(crossbeam_loom)))]
+impl_arithmetic!(u128, atomic::AtomicU128, "let a = AtomicCell::new(7u128);");
+#[cfg(all(has_atomic_u128, not(crossbeam_loom)))]
+impl_arithmetic!(i128, atomic::AtomicI128, "let  a = AtomicCell::new(7i128);");
 
 impl_arithmetic!(
     usize,
     atomic::AtomicUsize,
     "let a = AtomicCell::new(7usize);"
 );
+#[cfg(not(crossbeam_loom))]
 impl_arithmetic!(
     isize,
     atomic::AtomicIsize,
@@ -872,30 +552,6 @@
         a.fetch_and(val, Ordering::AcqRel)
     }
 
-    /// Applies logical "nand" to the current value and returns the previous value.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use crossbeam_utils::atomic::AtomicCell;
-    ///
-    /// let a = AtomicCell::new(true);
-    ///
-    /// assert_eq!(a.fetch_nand(false), true);
-    /// assert_eq!(a.load(), true);
-    ///
-    /// assert_eq!(a.fetch_nand(true), true);
-    /// assert_eq!(a.load(), false);
-    ///
-    /// assert_eq!(a.fetch_nand(false), false);
-    /// assert_eq!(a.load(), true);
-    /// ```
-    #[inline]
-    pub fn fetch_nand(&self, val: bool) -> bool {
-        let a = unsafe { &*(self.value.get() as *const AtomicBool) };
-        a.fetch_nand(val, Ordering::AcqRel)
-    }
-
     /// Applies logical "or" to the current value and returns the previous value.
     ///
     /// # Examples
@@ -1001,13 +657,105 @@
     // stored at addresses that are multiples of 3. It'd be too bad if `LEN` was divisible by 3.
     // In order to protect from such cases, we simply choose a large prime number for `LEN`.
     const LEN: usize = 97;
-    #[allow(clippy::declare_interior_mutable_const)]
-    const L: SeqLock = SeqLock::new();
+
     static LOCKS: [SeqLock; LEN] = [
-        L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,
-        L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,
-        L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L,
-        L, L, L, L, L, L, L,
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
+        SeqLock::new(),
     ];
 
     // If the modulus is a constant number, the compiler will use crazy math to transform this into
@@ -1030,6 +778,7 @@
     #[inline]
     fn swap(&self, _val: (), _order: Ordering) {}
 
+    #[allow(clippy::unnecessary_wraps)] // This is intentional.
     #[inline]
     fn compare_exchange_weak(
         &self,
@@ -1058,14 +807,18 @@
     ($t:ty, $a:ident, $atomic_op:expr, $fallback_op:expr) => {
         loop {
             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(not(crossbeam_no_atomic_64))]
+            #[cfg(has_atomic_u64)]
             atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op);
-            // TODO: AtomicU128 is unstable
-            // atomic!(@check, $t, atomic::AtomicU128, $a, $atomic_op);
+            #[cfg(has_atomic_u128)]
+            atomic!(@check, $t, atomic::AtomicU128, $a, $atomic_op);
 
             #[cfg(crossbeam_loom)]
             unimplemented!("loom does not support non-atomic atomic ops");
@@ -1078,14 +831,17 @@
 /// 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::AtomicU8>()
-        | can_transmute::<T, atomic::AtomicU16>()
-        | can_transmute::<T, atomic::AtomicU32>();
-    #[cfg(not(crossbeam_no_atomic_64))]
+    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 = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
-    // TODO: AtomicU128 is unstable
-    // let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
+    #[cfg(has_atomic_u128)]
+    let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
     is_lock_free
 }
 
diff --git a/src/atomic/consume.rs b/src/atomic/consume.rs
index 277b370..0fbd93e 100644
--- a/src/atomic/consume.rs
+++ b/src/atomic/consume.rs
@@ -1,6 +1,5 @@
 #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
 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.
@@ -26,7 +25,6 @@
     fn load_consume(&self) -> Self::Val;
 }
 
-#[cfg(not(crossbeam_no_atomic))]
 #[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
 macro_rules! impl_consume {
     () => {
@@ -39,7 +37,6 @@
     };
 }
 
-#[cfg(not(crossbeam_no_atomic))]
 #[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
 macro_rules! impl_consume {
     () => {
@@ -52,13 +49,12 @@
 
 macro_rules! impl_atomic {
     ($atomic:ident, $val:ty) => {
-        #[cfg(not(crossbeam_no_atomic))]
-        impl AtomicConsume for core::sync::atomic::$atomic {
+        impl AtomicConsume for ::core::sync::atomic::$atomic {
             type Val = $val;
             impl_consume!();
         }
         #[cfg(crossbeam_loom)]
-        impl AtomicConsume for loom::sync::atomic::$atomic {
+        impl AtomicConsume for ::loom::sync::atomic::$atomic {
             type Val = $val;
             impl_consume!();
         }
@@ -67,26 +63,32 @@
 
 impl_atomic!(AtomicBool, bool);
 impl_atomic!(AtomicUsize, usize);
+#[cfg(not(crossbeam_loom))]
 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(not(crossbeam_no_atomic_64))]
+#[cfg(has_atomic_u64)]
 impl_atomic!(AtomicU64, u64);
-#[cfg(not(crossbeam_no_atomic_64))]
+#[cfg(has_atomic_u64)]
 impl_atomic!(AtomicI64, i64);
 
-#[cfg(not(crossbeam_no_atomic))]
-impl<T> AtomicConsume for core::sync::atomic::AtomicPtr<T> {
+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> {
+impl<T> AtomicConsume for ::loom::sync::atomic::AtomicPtr<T> {
     type Val = *mut T;
     impl_consume!();
 }
diff --git a/src/atomic/mod.rs b/src/atomic/mod.rs
index fc713fc..874eaf2 100644
--- a/src/atomic/mod.rs
+++ b/src/atomic/mod.rs
@@ -3,9 +3,11 @@
 //! * [`AtomicCell`], a thread-safe mutable memory location.
 //! * [`AtomicConsume`], for reading from primitive atomic types with "consume" ordering.
 
-#[cfg(not(crossbeam_no_atomic_cas))]
 #[cfg(not(crossbeam_loom))]
-cfg_if::cfg_if! {
+use cfg_if::cfg_if;
+
+#[cfg(not(crossbeam_loom))]
+cfg_if! {
     // Use "wide" sequence lock if the pointer width <= 32 for preventing its counter against wrap
     // around.
     //
@@ -23,10 +25,8 @@
     }
 }
 
-#[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/src/lib.rs b/src/lib.rs
index 191c5a1..880d37e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -38,6 +38,7 @@
     unreachable_pub
 )]
 #![cfg_attr(not(feature = "std"), no_std)]
+#![cfg_attr(feature = "nightly", feature(cfg_target_has_atomic))]
 
 #[cfg(crossbeam_loom)]
 #[allow(unused_imports)]
@@ -46,8 +47,7 @@
         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,
+                AtomicBool, AtomicU16, AtomicU32, AtomicU64, AtomicU8, AtomicUsize,
             };
 
             // FIXME: loom does not support compiler_fence at the moment.
@@ -70,13 +70,15 @@
             // 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::{AtomicBool, AtomicIsize, AtomicUsize};
+            #[cfg(has_atomic_u16)]
+            pub(crate) use core::sync::atomic::{AtomicI16, AtomicU16};
+            #[cfg(has_atomic_u32)]
+            pub(crate) use core::sync::atomic::{AtomicI32, AtomicU32};
+            #[cfg(has_atomic_u64)]
             pub(crate) use core::sync::atomic::{AtomicI64, AtomicU64};
+            #[cfg(has_atomic_u8)]
+            pub(crate) use core::sync::atomic::{AtomicI8, AtomicU8};
         }
 
         #[cfg(feature = "std")]
@@ -84,6 +86,15 @@
     }
 }
 
+cfg_if! {
+    if #[cfg(feature = "alloc")] {
+        extern crate alloc;
+    } else if #[cfg(feature = "std")] {
+        extern crate std as alloc;
+    }
+}
+
+#[cfg_attr(feature = "nightly", cfg(target_has_atomic = "ptr"))]
 pub mod atomic;
 
 mod cache_padded;
diff --git a/src/sync/parker.rs b/src/sync/parker.rs
index 531f5a5..aefa515 100644
--- a/src/sync/parker.rs
+++ b/src/sync/parker.rs
@@ -175,7 +175,6 @@
     ///
     /// let p = Parker::new();
     /// let raw = Parker::into_raw(p);
-    /// # let _ = unsafe { Parker::from_raw(raw) };
     /// ```
     pub fn into_raw(this: Parker) -> *const () {
         Unparker::into_raw(this.unparker)
@@ -259,7 +258,6 @@
     /// let p = Parker::new();
     /// let u = p.unparker().clone();
     /// let raw = Unparker::into_raw(u);
-    /// # let _ = unsafe { Unparker::from_raw(raw) };
     /// ```
     pub fn into_raw(this: Unparker) -> *const () {
         Arc::into_raw(this.inner) as *const ()
diff --git a/src/thread.rs b/src/thread.rs
index a59a4f5..c57d076 100644
--- a/src/thread.rs
+++ b/src/thread.rs
@@ -446,7 +446,7 @@
                     unsafe { mem::transmute(closure) };
 
                 // Finally, spawn the closure.
-                self.builder.spawn(closure)?
+                self.builder.spawn(move || closure())?
             };
 
             let thread = handle.thread().clone();
diff --git a/tests/atomic_cell.rs b/tests/atomic_cell.rs
index da7a6e1..3d91d81 100644
--- a/tests/atomic_cell.rs
+++ b/tests/atomic_cell.rs
@@ -1,4 +1,3 @@
-use std::mem;
 use std::sync::atomic::AtomicUsize;
 use std::sync::atomic::Ordering::SeqCst;
 
@@ -9,47 +8,18 @@
     struct UsizeWrap(usize);
     struct U8Wrap(bool);
     struct I16Wrap(i16);
-    #[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_eq!(AtomicCell::<usize>::is_lock_free(), true);
+    assert_eq!(AtomicCell::<isize>::is_lock_free(), true);
+    assert_eq!(AtomicCell::<UsizeWrap>::is_lock_free(), true);
 
-    assert!(AtomicCell::<()>::is_lock_free());
+    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!(AtomicCell::<u8>::is_lock_free());
-    assert!(AtomicCell::<i8>::is_lock_free());
-    assert!(AtomicCell::<bool>::is_lock_free());
-    assert!(AtomicCell::<U8Wrap>::is_lock_free());
+    assert_eq!(AtomicCell::<I16Wrap>::is_lock_free(), cfg!(has_atomic_u16));
 
-    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());
+    assert_eq!(AtomicCell::<u128>::is_lock_free(), cfg!(has_atomic_u128));
 }
 
 #[test]
@@ -264,69 +234,3 @@
     CELL.store(1);
     assert_eq!(CELL.load(), 1);
 }
-
-// https://github.com/crossbeam-rs/crossbeam/pull/767
-macro_rules! test_arithmetic {
-    ($test_name:ident, $ty:ident) => {
-        #[test]
-        fn $test_name() {
-            let a: AtomicCell<$ty> = AtomicCell::new(7);
-
-            assert_eq!(a.fetch_add(3), 7);
-            assert_eq!(a.load(), 10);
-
-            assert_eq!(a.fetch_sub(3), 10);
-            assert_eq!(a.load(), 7);
-
-            assert_eq!(a.fetch_and(3), 7);
-            assert_eq!(a.load(), 3);
-
-            assert_eq!(a.fetch_or(16), 3);
-            assert_eq!(a.load(), 19);
-
-            assert_eq!(a.fetch_xor(2), 19);
-            assert_eq!(a.load(), 17);
-
-            assert_eq!(a.fetch_max(18), 17);
-            assert_eq!(a.load(), 18);
-
-            assert_eq!(a.fetch_min(17), 18);
-            assert_eq!(a.load(), 17);
-
-            assert_eq!(a.fetch_nand(7), 17);
-            assert_eq!(a.load(), !(17 & 7));
-        }
-    };
-}
-test_arithmetic!(arithmetic_u8, u8);
-test_arithmetic!(arithmetic_i8, i8);
-test_arithmetic!(arithmetic_u16, u16);
-test_arithmetic!(arithmetic_i16, i16);
-test_arithmetic!(arithmetic_u32, u32);
-test_arithmetic!(arithmetic_i32, i32);
-test_arithmetic!(arithmetic_u64, u64);
-test_arithmetic!(arithmetic_i64, i64);
-test_arithmetic!(arithmetic_u128, u128);
-test_arithmetic!(arithmetic_i128, i128);
-
-// https://github.com/crossbeam-rs/crossbeam/issues/748
-#[cfg_attr(miri, ignore)] // TODO
-#[rustversion::since(1.37)] // #[repr(align(N))] requires Rust 1.37
-#[test]
-fn issue_748() {
-    #[allow(dead_code)]
-    #[repr(align(8))]
-    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
-    enum Test {
-        Field(u32),
-        FieldLess,
-    }
-
-    assert_eq!(mem::size_of::<Test>(), 8);
-    assert_eq!(
-        AtomicCell::<Test>::is_lock_free(),
-        cfg!(not(crossbeam_no_atomic_64))
-    );
-    let x = AtomicCell::new(Test::FieldLess);
-    assert_eq!(x.load(), Test::FieldLess);
-}
diff --git a/tests/cache_padded.rs b/tests/cache_padded.rs
index 86e9a77..c9e7687 100644
--- a/tests/cache_padded.rs
+++ b/tests/cache_padded.rs
@@ -85,7 +85,6 @@
     assert_eq!(count.get(), 2);
 }
 
-#[allow(clippy::clone_on_copy)] // This is intentional.
 #[test]
 fn clone() {
     let a = CachePadded::new(17);
diff --git a/tests/sharded_lock.rs b/tests/sharded_lock.rs
index 0718b44..b4b8565 100644
--- a/tests/sharded_lock.rs
+++ b/tests/sharded_lock.rs
@@ -21,9 +21,6 @@
 #[test]
 fn frob() {
     const N: u32 = 10;
-    #[cfg(miri)]
-    const M: usize = 100;
-    #[cfg(not(miri))]
     const M: usize = 1000;
 
     let r = Arc::new(ShardedLock::new(()));
@@ -151,7 +148,7 @@
 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>>,
         }