It would be convenient if I could check if AtomicCells are lock-free at compile time. by marking AtomicCell<T>::is_lock_free() as a const fn.
For context, I'm working on an audio program in C++, due to C++ libraries including Qt. In audio programs, taking locks on the audio thread is regarded as unacceptable because it can block and cause the audio to stutter. As a result, I'd like to statically assert that a given atomic type written by the audio thread is lock-free. (I'm mostly looking at Rust for inspiration and comparison, to see whether parts of my code are nicer in C++ or Rust.)
|
pub fn is_lock_free() -> bool { |
|
atomic_is_lock_free::<T>() |
|
} |
calls atomic_is_lock_free<T>:
|
/// Returns `true` if operations on `AtomicCell<T>` are lock-free. |
|
fn atomic_is_lock_free<T>() -> bool { |
|
atomic! { T, _a, true, false } |
|
} |
expands to the atomic! macro:
|
macro_rules! atomic { |
|
// If values of type `$t` can be transmuted into values of the primitive atomic type `$atomic`, |
|
// declares variable `$a` of type `$atomic` and executes `$atomic_op`, breaking out of the loop. |
|
(@check, $t:ty, $atomic:ty, $a:ident, $atomic_op:expr) => { |
|
if can_transmute::<$t, $atomic>() { |
|
let $a: &$atomic; |
|
break $atomic_op; |
|
} |
|
}; |
|
|
|
// If values of type `$t` can be transmuted into values of a primitive atomic type, declares |
|
// variable `$a` of that type and executes `$atomic_op`. Otherwise, just executes |
|
// `$fallback_op`. |
|
($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(has_atomic_u64)] |
|
atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op); |
|
|
|
break $fallback_op; |
|
} |
|
}; |
|
} |
Marking AtomicCell<T>::is_lock_free() as const doesn't seem to cause issues, but depends on atomic_is_lock_free. Trying to mark atomic_is_lock_free as const fails on rust-lang/rust#49146 "Allow if and match in constants", and rust-lang/rust#52000 "Allow loop in constant evaluation".
From a cursory examination, atomic! doesn't truly need a loop, but depends on if. Note that I don't fully understand atomic! nor all call sites.
Are there any plans to mark this as a const fn, to allow users to statically assert it's lock-free? I don't know if atomic! needs to be split into two macros or not, with duplication and possible future desynchronization.
It would be convenient if I could check if AtomicCells are lock-free at compile time. by marking
AtomicCell<T>::is_lock_free()as a const fn.For context, I'm working on an audio program in C++, due to C++ libraries including Qt. In audio programs, taking locks on the audio thread is regarded as unacceptable because it can block and cause the audio to stutter. As a result, I'd like to statically assert that a given atomic type written by the audio thread is lock-free. (I'm mostly looking at Rust for inspiration and comparison, to see whether parts of my code are nicer in C++ or Rust.)
crossbeam/crossbeam-utils/src/atomic/atomic_cell.rs
Lines 108 to 110 in 81ab18e
calls
atomic_is_lock_free<T>:crossbeam/crossbeam-utils/src/atomic/atomic_cell.rs
Lines 809 to 812 in 81ab18e
expands to the
atomic!macro:crossbeam/crossbeam-utils/src/atomic/atomic_cell.rs
Lines 777 to 807 in 81ab18e
Marking
AtomicCell<T>::is_lock_free()asconstdoesn't seem to cause issues, but depends onatomic_is_lock_free. Trying to markatomic_is_lock_freeasconstfails on rust-lang/rust#49146 "Allowifandmatchin constants", and rust-lang/rust#52000 "Allowloopin constant evaluation".From a cursory examination,
atomic!doesn't truly need aloop, but depends onif. Note that I don't fully understandatomic!nor all call sites.Are there any plans to mark this as a const fn, to allow users to statically assert it's lock-free? I don't know if
atomic!needs to be split into two macros or not, with duplication and possible future desynchronization.