C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Lock-free atomic operations that use a different-sized type from the object or subobject

From: Pavel Vazharov <freakpv_at_[hidden]>
Date: Fri, 26 May 2023 17:06:34 +0300
Wouldn't this proposal cover such cases - https://wg21.link/p1478?

On Fri, May 26, 2023 at 5:01 PM John Platts via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> One feature that is missing from the C and C++ standards is to be able to
> do lock-free atomic accesses using a type that does not have the same size
> as the object (or subobject) being pointed to such as the following (at
> least in a portable way that does not involve undefined behavior):
>
> // ptr is aligned on a std::atomic_ref<uint32_t>::required_alignment
> boundary
> std::pair<std::uint32_t, bool>
> SomeFuncThatDoesU32AtomicAccess(std::uint8_t* ptr) {
> std::uint32_t u32_bits = lock_free_atomic_load_32(ptr,
> std::memory_order_relaxed);
> for(;;) {
> if((u32_bits & 0xFFFFu) == 0xFFFFu)
> return std::make_pair(u32_bits, false);
>
> const auto new_u32_bits = static_cast<std::uint32_t>(u32_bits + 1u);
> if(lock_free_compare_exchange_weak_32(ptr, u32_bits, new_u32_bits,
> std::memory_order_seq_cst, std::memory_order_relaxed))
> return std::make_pair(u32_bits, true);
> }
> }
>
> Note that memcpy cannot be used in the above code as memcpy can perform
> non-atomic accesses, as memcpy does an unconditional write, and as there is
> the possibility of data races on platforms that support threading.
>
> lock_free_atomic_load_32 is equivalent to the following, except that ptr
> can point to any valid memory location (including the case where any of the
> bytes accessed point to bytes of a volatile object and including the case
> where ptr points to read-only memory) where at least sizeof(std::uint32_t)
> bytes are readable and whose alignment is at least
> std::atomic_ref<uint32_t>::required_alignment):
> std::uint32_t lock_free_atomic_load_32(const volatile void* ptr,
> std::memory_order order) {
> std::atomic_ref<std::uint32_t> u32_atomic_ref(
> *reinterpret_cast<std::uint32_t*>(const_cast<void*>(ptr)));
> return u32_atomic_ref.load(order);
> }
>
> lock_free_compare_exchange_weak_32 is equivalent to the following, except
> that ptr can point to any valid memory location (including the case where
> any of the bytes accessed point to bytes of a volatile object) where at
> least sizeof(std::uint32_t) bytes are writable and whose alignment is at
> least std::atomic_ref<uint32_t>::required_alignment):
> bool lock_free_compare_exchange_weak_32(volatile void* ptr,
> std::uint32_t& expected,
> std::uint32_t desired,
> std::memory_order success,
> std::memory_order failure) {
> std::atomic_ref<std::uint32_t> u32_atomic_ref(
> *reinterpret_cast<std::uint32_t*>(const_cast<void*>(ptr)));
> return u32_atomic_ref.compare_exchange_weak(expected, desired, success,
> failure);
> }
>
> Adding lock-free atomic operations that can operate on any valid pointer
> to a suitably-aligned type such as lock_free_atomic_load_32,
> lock_free_atomic_store_32, lock_free_compare_exchange_weak_32, and
> lock_free_compare_exchange_strong_32 addresses issues that are not
> addressed by the std::memcpy and std::bit_cast operations.
>
> Having functions such as lock_free_atomic_load_32,
> lock_free_atomic_store_32, lock_free_compare_exchange_weak_32, and
> lock_free_compare_exchange_strong_32 would also allow C and C++ programmers
> to eliminate type punning in cases where std::memcpy cannot be used (due to
> the need to access memory that might be concurrently accessed in a
> lock-free atomic manner).
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2023-05-26 14:06:48