lundi 2 janvier 2017

Release-Consume ordering for reference counting

Consider the following simple reference counting functions (to be used with boost::intrusive_ptr):

class Foo {
    // ...

    std::atomic<std::size_t> refCount_{0};

    friend void intrusive_ptr_add_ref(Foo* ptr)
    {
        ++ptr->refCount_;  // ❶
    }

    friend void intrusive_ptr_release(Foo* ptr)
    {
        if (--ptr->refCount_ == 0) {  // ❷
            delete ptr;
    }
};

I'm still learning memory ordering, and I'm wondering if the default memory ordering for fetch_add/sub (memory_order_seq_cst) is too strict in this case. Since the only ordering I want to ensure is between the store ❶ and load ❷, I think we can replace ❶ with

ptr->refCount_.fetch_add(1, std::memory_order_release);

And replace ❷ with

if (ptr->refCount_.fetch_sub(1, std::memory_ordering_consume) == 1) {

But memory ordering is still new and subtle to me, so I'm not sure if this will work correctly. Did I miss anything?

Aucun commentaire:

Enregistrer un commentaire