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 = is_lock_free | can_transmute::<T, atomic::AtomicU64>();
// TODO: AtomicU128 is unstable
// let is_lock_free = is_lock_free | can_transmute::<T, atomic::AtomicU128>();
is_lock_free
}
I am not familiar with this code, but it looks like: up to u32, it is lock free, u64 may or may not be lock free, and beyond u64 it uses locks. Is that correct ?
Is the best we can do here: add a level of indirection.
I.e. we have a Vec<T>, have different threads write to different locations of this Vec. Then, we overwrite a usize atomically, which points to which entry of the Vec<T> we want.
Suppose we can bound the number of threads as N, and then we create a vec![T; 2 * N]. Each thread is assigned 2 locs, ensuring it never writes to the one being read.