Skip to content

Why is std::memory_order_relaxed enough for atomic_conditional_increment? #107

@kakashidinho

Description

@kakashidinho

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions