diff --git a/.clippy.toml b/.clippy.toml deleted file mode 100644 index 749c3b58a..000000000 --- a/.clippy.toml +++ /dev/null @@ -1 +0,0 @@ -msrv = "1.38" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7bb15f0e1..08325e745 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,9 +58,9 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - - name: Install Rust - # --no-self-update is necessary because the windows environment cannot self-update rustup.exe. - run: rustup update ${{ matrix.rust }} --no-self-update && rustup default ${{ matrix.rust }} + - uses: dtolnay/rust-toolchain@v1 + with: + toolchain: ${{ matrix.rust }} - name: Install cross uses: taiki-e/install-action@cross if: matrix.target != '' @@ -80,8 +80,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install Rust - run: rustup update ${{ matrix.rust }} && rustup default ${{ matrix.rust }} + - uses: dtolnay/rust-toolchain@v1 + with: + toolchain: ${{ matrix.rust }} - name: Install cargo-hack uses: taiki-e/install-action@cargo-hack - name: Check features @@ -92,10 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install Rust - run: rustup update nightly && rustup default nightly + - uses: dtolnay/rust-toolchain@nightly - name: Install cargo-hack uses: taiki-e/install-action@cargo-hack + - name: Install cargo-minimal-versions + uses: taiki-e/install-action@cargo-minimal-versions - name: dependency tree check run: ./ci/dependencies.sh @@ -107,8 +109,7 @@ jobs: pull-requests: write steps: - uses: actions/checkout@v3 - - name: Install Rust - run: rustup update nightly && rustup default nightly + - uses: dtolnay/rust-toolchain@nightly - run: ci/no_atomic.sh - run: git add -N . && git diff --exit-code if: github.repository_owner != 'crossbeam-rs' || github.event_name != 'schedule' @@ -140,28 +141,27 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install Rust - run: rustup update stable + - uses: dtolnay/rust-toolchain@stable - name: rustfmt run: ./ci/rustfmt.sh - # Check clippy. - clippy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Install Rust - run: rustup update stable - - name: clippy - run: ./ci/clippy.sh + # This branch no longer actively developed. Most commits to this + # branch are backporting and should not be blocked by clippy. + # # Check clippy. + # clippy: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v3 + # - uses: dtolnay/rust-toolchain@stable + # - name: clippy + # run: ./ci/clippy.sh # Run miri. miri: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install Rust - run: rustup toolchain install nightly --component miri && rustup default nightly + - uses: dtolnay/rust-toolchain@miri - name: miri run: ./ci/miri.sh @@ -170,8 +170,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install Rust - run: rustup update nightly && rustup default nightly + - uses: dtolnay/rust-toolchain@nightly - name: Run sanitizers run: ./ci/san.sh @@ -180,8 +179,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install Rust - run: rustup update stable + - uses: dtolnay/rust-toolchain@stable - name: loom run: ./ci/crossbeam-epoch-loom.sh @@ -190,8 +188,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install Rust - run: rustup update nightly && rustup default nightly + - uses: dtolnay/rust-toolchain@nightly - name: docs run: ./ci/docs.sh @@ -218,11 +215,12 @@ jobs: - dependencies - codegen - rustfmt - - clippy + # - clippy - miri - san - loom - docs + - shellcheck runs-on: ubuntu-latest steps: - name: Mark the job as a success diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5ada352f3..f72c18d2f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,10 +9,6 @@ on: - crossbeam-[0-9]+.* - crossbeam-[a-z]+-[0-9]+.* -env: - RUSTFLAGS: -Dwarnings - RUST_BACKTRACE: 1 - defaults: run: shell: bash diff --git a/ci/dependencies.sh b/ci/dependencies.sh index c80adc5ff..9a39850a3 100755 --- a/ci/dependencies.sh +++ b/ci/dependencies.sh @@ -7,10 +7,4 @@ cargo tree cargo tree --duplicate # Check minimal versions. -# Remove dev-dependencies from Cargo.toml to prevent the next `cargo update` -# from determining minimal versions based on dev-dependencies. -cargo hack --remove-dev-deps --workspace -# Update Cargo.lock to minimal version dependencies. -cargo update -Zminimal-versions -cargo tree -cargo hack check --all --all-features --exclude benchmarks +cargo minimal-versions build --workspace --all-features --exclude benchmarks diff --git a/ci/rustfmt.sh b/ci/rustfmt.sh index 524b2f57c..b0d479eea 100755 --- a/ci/rustfmt.sh +++ b/ci/rustfmt.sh @@ -5,4 +5,4 @@ cd "$(dirname "$0")"/.. rustup component add rustfmt -cargo fmt --all -- --check +cargo fmt --all --check diff --git a/crossbeam-channel/src/channel.rs b/crossbeam-channel/src/channel.rs index 800fe6352..7871bcb70 100644 --- a/crossbeam-channel/src/channel.rs +++ b/crossbeam-channel/src/channel.rs @@ -160,7 +160,7 @@ pub fn bounded(cap: usize) -> (Sender, Receiver) { /// let ms = |ms| Duration::from_millis(ms); /// /// // Returns `true` if `a` and `b` are very close `Instant`s. -/// let eq = |a, b| a + ms(50) > b && b + ms(50) > a; +/// let eq = |a, b| a + ms(60) > b && b + ms(60) > a; /// /// let start = Instant::now(); /// let r = after(ms(100)); diff --git a/crossbeam-channel/tests/golang.rs b/crossbeam-channel/tests/golang.rs index 8050716c6..41149f485 100644 --- a/crossbeam-channel/tests/golang.rs +++ b/crossbeam-channel/tests/golang.rs @@ -9,7 +9,7 @@ //! - https://golang.org/LICENSE //! - https://golang.org/PATENTS -#![allow(clippy::mutex_atomic, clippy::redundant_clone)] +#![allow(clippy::redundant_clone)] use std::alloc::{GlobalAlloc, Layout, System}; use std::any::Any; diff --git a/crossbeam-channel/tests/ready.rs b/crossbeam-channel/tests/ready.rs index d8dd6ceb5..6e3fb2b64 100644 --- a/crossbeam-channel/tests/ready.rs +++ b/crossbeam-channel/tests/ready.rs @@ -229,6 +229,7 @@ fn default_when_disconnected() { } #[test] +#[cfg_attr(miri, ignore)] // this test makes timing assumptions, but Miri is so slow it violates them fn default_only() { let start = Instant::now(); diff --git a/crossbeam-deque/src/lib.rs b/crossbeam-deque/src/lib.rs index b696b5f96..16bc728b3 100644 --- a/crossbeam-deque/src/lib.rs +++ b/crossbeam-deque/src/lib.rs @@ -95,7 +95,6 @@ rust_2018_idioms, unreachable_pub )] -#![allow(clippy::question_mark)] // https://github.com/rust-lang/rust-clippy/issues/8281 #![cfg_attr(not(feature = "std"), no_std)] use cfg_if::cfg_if; diff --git a/crossbeam-epoch/CHANGELOG.md b/crossbeam-epoch/CHANGELOG.md index b05a52dfc..3aac87b7f 100644 --- a/crossbeam-epoch/CHANGELOG.md +++ b/crossbeam-epoch/CHANGELOG.md @@ -1,3 +1,8 @@ +# Version 0.9.11 + +- Removes the dependency on the `once_cell` crate to restore the MSRV. (#913) +- Work around [rust-lang#98302](https://github.com/rust-lang/rust/issues/98302), which causes compile error on windows-gnu when LTO is enabled. (#913) + # Version 0.9.10 - Bump the minimum supported Rust version to 1.38. (#877) diff --git a/crossbeam-epoch/Cargo.toml b/crossbeam-epoch/Cargo.toml index f40369306..822e04c7d 100644 --- a/crossbeam-epoch/Cargo.toml +++ b/crossbeam-epoch/Cargo.toml @@ -4,7 +4,7 @@ name = "crossbeam-epoch" # - Update CHANGELOG.md # - Update README.md # - Create "crossbeam-epoch-X.Y.Z" git tag -version = "0.9.10" +version = "0.9.11" edition = "2018" rust-version = "1.38" license = "MIT OR Apache-2.0" @@ -19,7 +19,7 @@ default = ["std"] # Enable to use APIs that require `std`. # This is enabled by default. -std = ["alloc", "crossbeam-utils/std", "once_cell"] +std = ["alloc", "crossbeam-utils/std"] # Enable to use APIs that require `alloc`. # This is enabled by default and also enabled if the `std` feature is enabled. @@ -48,7 +48,6 @@ autocfg = "1" [dependencies] cfg-if = "1" memoffset = "0.6" -once_cell = { version = "1", optional = true } scopeguard = { version = "1.1", default-features = false } # Enable the use of loom for concurrency testing. diff --git a/crossbeam-epoch/src/default.rs b/crossbeam-epoch/src/default.rs index c2b4852a4..b42c1c7a7 100644 --- a/crossbeam-epoch/src/default.rs +++ b/crossbeam-epoch/src/default.rs @@ -8,22 +8,30 @@ use crate::collector::{Collector, LocalHandle}; use crate::guard::Guard; use crate::primitive::thread_local; #[cfg(not(crossbeam_loom))] -use once_cell::sync::Lazy; +use crate::sync::once_lock::OnceLock; -/// The global data for the default garbage collector. -#[cfg(not(crossbeam_loom))] -static COLLECTOR: Lazy = Lazy::new(Collector::new); -// FIXME: loom does not currently provide the equivalent of Lazy: -// https://github.com/tokio-rs/loom/issues/263 -#[cfg(crossbeam_loom)] -loom::lazy_static! { - /// The global data for the default garbage collector. - static ref COLLECTOR: Collector = Collector::new(); +fn collector() -> &'static Collector { + #[cfg(not(crossbeam_loom))] + { + /// The global data for the default garbage collector. + static COLLECTOR: OnceLock = OnceLock::new(); + COLLECTOR.get_or_init(Collector::new) + } + // FIXME: loom does not currently provide the equivalent of Lazy: + // https://github.com/tokio-rs/loom/issues/263 + #[cfg(crossbeam_loom)] + { + loom::lazy_static! { + /// The global data for the default garbage collector. + static ref COLLECTOR: Collector = Collector::new(); + } + &COLLECTOR + } } thread_local! { /// The per-thread participant for the default garbage collector. - static HANDLE: LocalHandle = COLLECTOR.register(); + static HANDLE: LocalHandle = collector().register(); } /// Pins the current thread. @@ -40,7 +48,7 @@ pub fn is_pinned() -> bool { /// Returns the default global collector. pub fn default_collector() -> &'static Collector { - &COLLECTOR + collector() } #[inline] @@ -50,7 +58,7 @@ where { HANDLE .try_with(|h| f(h)) - .unwrap_or_else(|_| f(&COLLECTOR.register())) + .unwrap_or_else(|_| f(&collector().register())) } #[cfg(all(test, not(crossbeam_loom)))] diff --git a/crossbeam-epoch/src/lib.rs b/crossbeam-epoch/src/lib.rs index 4cf982b6b..b432c1f40 100644 --- a/crossbeam-epoch/src/lib.rs +++ b/crossbeam-epoch/src/lib.rs @@ -107,7 +107,7 @@ mod primitive { // https://github.com/tokio-rs/loom#handling-loom-api-differences impl UnsafeCell { #[inline] - pub(crate) fn new(data: T) -> UnsafeCell { + pub(crate) const fn new(data: T) -> UnsafeCell { UnsafeCell(::core::cell::UnsafeCell::new(data)) } diff --git a/crossbeam-epoch/src/sync/mod.rs b/crossbeam-epoch/src/sync/mod.rs index 5c06e7643..08981be25 100644 --- a/crossbeam-epoch/src/sync/mod.rs +++ b/crossbeam-epoch/src/sync/mod.rs @@ -1,4 +1,7 @@ //! Synchronization primitives. pub(crate) mod list; +#[cfg(feature = "std")] +#[cfg(not(crossbeam_loom))] +pub(crate) mod once_lock; pub(crate) mod queue; diff --git a/crossbeam-epoch/src/sync/once_lock.rs b/crossbeam-epoch/src/sync/once_lock.rs new file mode 120000 index 000000000..6e7443034 --- /dev/null +++ b/crossbeam-epoch/src/sync/once_lock.rs @@ -0,0 +1 @@ +../../../crossbeam-utils/src/sync/once_lock.rs \ No newline at end of file diff --git a/crossbeam-skiplist/tests/base.rs b/crossbeam-skiplist/tests/base.rs index 1c08dea42..d6517f086 100644 --- a/crossbeam-skiplist/tests/base.rs +++ b/crossbeam-skiplist/tests/base.rs @@ -1,4 +1,4 @@ -#![allow(clippy::mutex_atomic, clippy::redundant_clone)] +#![allow(clippy::redundant_clone)] use std::ops::Bound; use std::sync::atomic::{AtomicUsize, Ordering}; diff --git a/crossbeam-skiplist/tests/map.rs b/crossbeam-skiplist/tests/map.rs index 4ea2948f6..e09cb3919 100644 --- a/crossbeam-skiplist/tests/map.rs +++ b/crossbeam-skiplist/tests/map.rs @@ -1,5 +1,3 @@ -#![allow(clippy::mutex_atomic)] - use std::{iter, ops::Bound, sync::Barrier}; use crossbeam_skiplist::SkipMap; diff --git a/crossbeam-utils/CHANGELOG.md b/crossbeam-utils/CHANGELOG.md index 28812e1d6..3a93e4659 100644 --- a/crossbeam-utils/CHANGELOG.md +++ b/crossbeam-utils/CHANGELOG.md @@ -1,3 +1,8 @@ +# Version 0.8.12 + +- Removes the dependency on the `once_cell` crate to restore the MSRV. (#913) +- Work around [rust-lang#98302](https://github.com/rust-lang/rust/issues/98302), which causes compile error on windows-gnu when LTO is enabled. (#913) + # Version 0.8.11 - Bump the minimum supported Rust version to 1.38. (#877) diff --git a/crossbeam-utils/Cargo.toml b/crossbeam-utils/Cargo.toml index e4e5a9a42..7679a70ab 100644 --- a/crossbeam-utils/Cargo.toml +++ b/crossbeam-utils/Cargo.toml @@ -4,7 +4,7 @@ name = "crossbeam-utils" # - Update CHANGELOG.md # - Update README.md # - Create "crossbeam-utils-X.Y.Z" git tag -version = "0.8.11" +version = "0.8.12" edition = "2018" rust-version = "1.38" license = "MIT OR Apache-2.0" @@ -19,7 +19,7 @@ default = ["std"] # Enable to use APIs that require `std`. # This is enabled by default. -std = ["once_cell"] +std = [] # These features are no longer used. # TODO: remove in the next major version. @@ -32,7 +32,6 @@ nightly = [] [dependencies] cfg-if = "1" -once_cell = { version = "1", optional = true } # Enable the use of loom for concurrency testing. # diff --git a/crossbeam-utils/src/cache_padded.rs b/crossbeam-utils/src/cache_padded.rs index 822e831d1..b5d5d33c9 100644 --- a/crossbeam-utils/src/cache_padded.rs +++ b/crossbeam-utils/src/cache_padded.rs @@ -39,9 +39,9 @@ use core::ops::{Deref, DerefMut}; /// let addr1 = &*array[0] as *const i8 as usize; /// let addr2 = &*array[1] as *const i8 as usize; /// -/// assert!(addr2 - addr1 >= 64); -/// assert_eq!(addr1 % 64, 0); -/// assert_eq!(addr2 % 64, 0); +/// assert!(addr2 - addr1 >= 32); +/// assert_eq!(addr1 % 32, 0); +/// assert_eq!(addr2 % 32, 0); /// ``` /// /// When building a concurrent queue with a head and a tail index, it is wise to place them in diff --git a/crossbeam-utils/src/sync/mod.rs b/crossbeam-utils/src/sync/mod.rs index eeb740c2c..f9eec71fb 100644 --- a/crossbeam-utils/src/sync/mod.rs +++ b/crossbeam-utils/src/sync/mod.rs @@ -4,6 +4,8 @@ //! * [`ShardedLock`], a sharded reader-writer lock with fast concurrent reads. //! * [`WaitGroup`], for synchronizing the beginning or end of some computation. +#[cfg(not(crossbeam_loom))] +mod once_lock; mod parker; #[cfg(not(crossbeam_loom))] mod sharded_lock; diff --git a/crossbeam-utils/src/sync/once_lock.rs b/crossbeam-utils/src/sync/once_lock.rs new file mode 100644 index 000000000..c1fefc96c --- /dev/null +++ b/crossbeam-utils/src/sync/once_lock.rs @@ -0,0 +1,103 @@ +// Based on unstable std::sync::OnceLock. +// +// Source: https://github.com/rust-lang/rust/blob/8e9c93df464b7ada3fc7a1c8ccddd9dcb24ee0a0/library/std/src/sync/once_lock.rs + +use core::cell::UnsafeCell; +use core::mem::MaybeUninit; +use core::sync::atomic::{AtomicBool, Ordering}; +use std::sync::Once; + +pub(crate) struct OnceLock { + once: Once, + // Once::is_completed requires Rust 1.43, so use this to track of whether they have been initialized. + is_initialized: AtomicBool, + value: UnsafeCell>, + // Unlike std::sync::OnceLock, we don't need PhantomData here because + // we don't use #[may_dangle]. +} + +unsafe impl Sync for OnceLock {} +unsafe impl Send for OnceLock {} + +impl OnceLock { + /// Creates a new empty cell. + #[must_use] + pub(crate) const fn new() -> Self { + Self { + once: Once::new(), + is_initialized: AtomicBool::new(false), + value: UnsafeCell::new(MaybeUninit::uninit()), + } + } + + /// Gets the contents of the cell, initializing it with `f` if the cell + /// was empty. + /// + /// Many threads may call `get_or_init` concurrently with different + /// initializing functions, but it is guaranteed that only one function + /// will be executed. + /// + /// # Panics + /// + /// If `f` panics, the panic is propagated to the caller, and the cell + /// remains uninitialized. + /// + /// It is an error to reentrantly initialize the cell from `f`. The + /// exact outcome is unspecified. Current implementation deadlocks, but + /// this may be changed to a panic in the future. + pub(crate) fn get_or_init(&self, f: F) -> &T + where + F: FnOnce() -> T, + { + // Fast path check + if self.is_initialized() { + // SAFETY: The inner value has been initialized + return unsafe { self.get_unchecked() }; + } + self.initialize(f); + + debug_assert!(self.is_initialized()); + + // SAFETY: The inner value has been initialized + unsafe { self.get_unchecked() } + } + + #[inline] + fn is_initialized(&self) -> bool { + self.is_initialized.load(Ordering::Acquire) + } + + #[cold] + fn initialize(&self, f: F) + where + F: FnOnce() -> T, + { + let slot = self.value.get().cast::(); + let is_initialized = &self.is_initialized; + + self.once.call_once(|| { + let value = f(); + unsafe { + slot.write(value); + } + is_initialized.store(true, Ordering::Release); + }); + } + + /// # Safety + /// + /// The value must be initialized + unsafe fn get_unchecked(&self) -> &T { + debug_assert!(self.is_initialized()); + &*self.value.get().cast::() + } +} + +impl Drop for OnceLock { + fn drop(&mut self) { + if self.is_initialized() { + // SAFETY: The inner value has been initialized + unsafe { self.value.get().cast::().drop_in_place() }; + } + } +} diff --git a/crossbeam-utils/src/sync/sharded_lock.rs b/crossbeam-utils/src/sync/sharded_lock.rs index 692653447..b43c55ea4 100644 --- a/crossbeam-utils/src/sync/sharded_lock.rs +++ b/crossbeam-utils/src/sync/sharded_lock.rs @@ -9,8 +9,8 @@ use std::sync::{LockResult, PoisonError, TryLockError, TryLockResult}; use std::sync::{Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::thread::{self, ThreadId}; +use crate::sync::once_lock::OnceLock; use crate::CachePadded; -use once_cell::sync::Lazy; /// The number of shards per sharded lock. Must be a power of two. const NUM_SHARDS: usize = 8; @@ -583,13 +583,17 @@ struct ThreadIndices { next_index: usize, } -static THREAD_INDICES: Lazy> = Lazy::new(|| { - Mutex::new(ThreadIndices { - mapping: HashMap::new(), - free_list: Vec::new(), - next_index: 0, - }) -}); +fn thread_indices() -> &'static Mutex { + static THREAD_INDICES: OnceLock> = OnceLock::new(); + fn init() -> Mutex { + Mutex::new(ThreadIndices { + mapping: HashMap::new(), + free_list: Vec::new(), + next_index: 0, + }) + } + THREAD_INDICES.get_or_init(init) +} /// A registration of a thread with an index. /// @@ -601,7 +605,7 @@ struct Registration { impl Drop for Registration { fn drop(&mut self) { - let mut indices = THREAD_INDICES.lock().unwrap(); + let mut indices = thread_indices().lock().unwrap(); indices.mapping.remove(&self.thread_id); indices.free_list.push(self.index); } @@ -610,7 +614,7 @@ impl Drop for Registration { thread_local! { static REGISTRATION: Registration = { let thread_id = thread::current().id(); - let mut indices = THREAD_INDICES.lock().unwrap(); + let mut indices = thread_indices().lock().unwrap(); let index = match indices.free_list.pop() { Some(i) => i, diff --git a/crossbeam-utils/src/sync/wait_group.rs b/crossbeam-utils/src/sync/wait_group.rs index 4206ee42b..19d607415 100644 --- a/crossbeam-utils/src/sync/wait_group.rs +++ b/crossbeam-utils/src/sync/wait_group.rs @@ -1,6 +1,3 @@ -// Necessary for using `Mutex` for conditional variables -#![allow(clippy::mutex_atomic)] - use crate::primitive::sync::{Arc, Condvar, Mutex}; use std::fmt; @@ -42,6 +39,7 @@ use std::fmt; /// /// // Block until all threads have finished their work. /// wg.wait(); +/// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 /// ``` /// /// [`Barrier`]: std::sync::Barrier @@ -100,6 +98,7 @@ impl WaitGroup { /// /// // Block until both threads have reached `wait()`. /// wg.wait(); + /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371 /// ``` pub fn wait(self) { if *self.inner.count.lock().unwrap() == 1 { diff --git a/no_atomic.rs b/no_atomic.rs index f740aaee1..675d9a27e 100644 --- a/no_atomic.rs +++ b/no_atomic.rs @@ -2,6 +2,8 @@ // It is not intended for manual editing. const NO_ATOMIC_CAS: &[&str] = &[ + "armv4t-none-eabi", + "armv5te-none-eabi", "avr-unknown-gnu-atmega328", "bpfeb-unknown-none", "bpfel-unknown-none", @@ -10,6 +12,7 @@ const NO_ATOMIC_CAS: &[&str] = &[ "riscv32im-unknown-none-elf", "riscv32imc-unknown-none-elf", "thumbv4t-none-eabi", + "thumbv5te-none-eabi", "thumbv6m-none-eabi", ]; @@ -18,7 +21,9 @@ const NO_ATOMIC_64: &[&str] = &[ "arm-linux-androideabi", "armebv7r-none-eabi", "armebv7r-none-eabihf", + "armv4t-none-eabi", "armv4t-unknown-linux-gnueabi", + "armv5te-none-eabi", "armv5te-unknown-linux-gnueabi", "armv5te-unknown-linux-musleabi", "armv5te-unknown-linux-uclibceabi", @@ -55,6 +60,7 @@ const NO_ATOMIC_64: &[&str] = &[ "riscv32imac-unknown-xous-elf", "riscv32imc-unknown-none-elf", "thumbv4t-none-eabi", + "thumbv5te-none-eabi", "thumbv6m-none-eabi", "thumbv7em-none-eabi", "thumbv7em-none-eabihf",