Inside STL: Waiting for a std::atomic to change, part 2 -- Raymond Chen

RaymondChen_5in-150x150.jpgLast time, we looked at how the Microsoft C++ standard library implements wait and notify_* for std::atomic<std::shared_ptr<T>>. Today, we’ll look at the other library that (as of this writing) implements std::atomic<std::shared_ptr<T>>: libstdc++.

Inside STL: Waiting for a std::atomic<std::shared_ptr<T>> to change, part 2

by Raymond Chen

From the article:

The first thing to note is that the traditional “wait for a value to change” mechanism on unix is the futex, but futexes (futexen?) are limited to 4-byte values, which is insufficient for a 64-bit pointer, much less the two pointers inside a shared_ptr.

At this point, I will refer you to learn about how libstdc++ implements waits on atomic values, particularly the section on how it handles types that do not fit in a __platform_wait_t. The remainder of this discussion will treat that as an already-solved problem and focus on the shared pointer part.

Okay, back to atomic<shared_ptr<T>>::wait():

// atomic<shared_ptr<T>>::wait
void
wait(value_type __old,
     memory_order __o = memory_order_seq_cst) const noexcept
{
    _M_impl.wait(std::move(__old), __o);
}

When you wait on a shared_ptr, the work is done by _Sp_atomic::wait:

// _Sp_atomic<shared_ptr<T>>::wait
void
wait(value_type __old, memory_order __o) const noexcept
{
    auto __pi = _M_refcount.lock(memory_order_acquire);
    if (_M_ptr == __old._M_ptr && __pi == __old._M_refcount._M_pi)
      _M_refcount._M_wait_unlock(__o);
    else
      _M_refcount.unlock(memory_order_relaxed);
}

Add a Comment

Comments are closed.

Comments (0)

There are currently no comments on this entry.