diff --git a/src/control/controlvalue.h b/src/control/controlvalue.h index f7e718897a6..0858c6dc807 100644 --- a/src/control/controlvalue.h +++ b/src/control/controlvalue.h @@ -64,6 +64,8 @@ class ControlRingValue { private: T m_value; mutable std::atomic m_readerSlots; + static_assert(std::atomic::is_always_lock_free, + "atomics used for lock-free data storage are not lock-free"); }; // Ring buffer based implementation for all Types sizeof(T) > sizeof(void*) @@ -123,6 +125,8 @@ class ControlValueAtomicBase { ControlRingValue m_ring[cRingSize]; std::atomic m_readIndex; std::atomic m_writeIndex; + static_assert(std::atomic::is_always_lock_free, + "atomics used for lock-free data storage are not lock-free"); }; // Specialized template for types that are deemed to be atomic on the target @@ -146,6 +150,7 @@ class ControlValueAtomicBase { private: std::atomic m_value; + static_assert(std::atomic::is_always_lock_free); }; template @@ -156,6 +161,12 @@ class ControlValueAtomic : public ControlValueAtomicBase::is_always_lock_free>; + static_assert(!(!std::atomic::is_always_lock_free && + sizeof(T) <= sizeof(void*)), + "T is not lock free even though it is smaller than void*! Consider " + "using `std::atomic::is_lock_free()` to only fallback to the " + "eventually-consistent ControlValueAtomicBase when necessary"); + public: ControlValueAtomic() = default; ControlValueAtomic(const T& value)