You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I'm just trying to understand the rationale behind the using of std::memory_order_relaxed in sp_counted_base_std_atomic.hpp's atomic_conditional_increment's implementation.
atomic_conditional_increment's implementation (click to expand)
inline std::int_least32_t atomic_conditional_increment( std::atomic_int_least32_t * pw ) BOOST_SP_NOEXCEPT
{
// long r = *pw;
// if( r != 0 ) ++*pw;
// return r;
std::int_least32_t r = pw->load( std::memory_order_relaxed );
for( ;; )
{
if( r == 0 )
{
return r;
}
if( pw->compare_exchange_weak( r, r + 1, std::memory_order_relaxed, std::memory_order_relaxed ) )
{
return r;
}
}
}
AFAIK this function is used by weak_ptr to obtain the shared_ptr if the obj is still alive (ref count is still > 0).
Consider the following case:
shared_ptr A;
if ((A = weak_ptr.lock()) != nullptr) // internally does `if (atomic_conditional_increment() != 0)`
{
// modify object pointed by A
}
Shouldn't we use std::memory_order_acquire to ensure that the modification of object pointed by A won't be reordered before the nullptr check?
The text was updated successfully, but these errors were encountered:
The nullptr check and the modification would be on the same side of the acquire anyway, so they can still be "reordered".
"Reordered" is not the right way to think about this anyway, because operations are never observably reordered within the same thread. In order for "reordering" to be observed, there needs to be another thread that can perceive events in a different order.
Try adding another thread to the example and see if you can demonstrate a problem.
Honestly I'm not an expert in C++ memory order. So I'm using this question in hope it could help me understand a bit better.
I meant the modification could be reordered to before the ref count is increased successfully/unsuccessfully by compare_exchange_weak.
What if at the same time other thread does the decrement of ref count to zero, and deletes the object? Could it be possible to happen?
Though this most likely leads to a wrong prediction, and the processor could throw away the modification's results on the 1st thread anw. If I understand correctly how processor's branch prediction works.
What if at the same time other thread does the decrement of ref count to zero, and deletes the object? Could it be possible to happen?
No, because if this happens first, the atomic_conditional_increment will fail, and if it happens second, the reference count will not be zero so the object won't be destroyed.
Hi, I'm just trying to understand the rationale behind the using of
std::memory_order_relaxed
in sp_counted_base_std_atomic.hpp'satomic_conditional_increment
's implementation.atomic_conditional_increment's implementation (click to expand)
AFAIK this function is used by
weak_ptr
to obtain theshared_ptr
if the obj is still alive (ref count is still > 0).Consider the following case:
Shouldn't we use
std::memory_order_acquire
to ensure that the modification of object pointed by A won't be reordered before thenullptr
check?The text was updated successfully, but these errors were encountered: