Boost logo

Boost Users :

Subject: Re: [Boost-users] Boost.Atomic documentation, Reference Counting
From: Anthony Williams (anthony.ajw_at_[hidden])
Date: 2012-04-23 04:12:16


On 23/04/12 08:26, Václav Zeman wrote:
> Your documentation to Boost.Atomic ([1]) has been given me as an
> answer to my StackOverflow ([2]) question. Here is a snippet from the
> documentation:
>
> friend void intrusive_ptr_release(const X * x)
> {
> if (x->refcount_.fetch_sub(1, boost::memory_order_release) == 1) {
> boost::atomic_thread_fence(boost::memory_order_acquire);
> delete x;
> }
> }
>
> And your rationale: "It is important to enforce any possible access to
> the object in one thread (through an existing reference) to happen
> before deleting the object in a different thread. This is achieved by
> a "release" operation after dropping a reference (any access to the
> object through this reference must obviously happened before), and an
> "acquire" operation before deleting the object."
>
> I wonder why this would not work well if it looked like this instead:
>
> friend void intrusive_ptr_release(const X * x)
> {
> if (x->refcount_.fetch_sub(1, boost::memory_order_relaxed) == 1) {
> boost::atomic_thread_fence(boost::memory_order_acq_rel);
> delete x;
> }
> }

If 2 threads A and B have a reference to the object, and both drop their
references then one thread will delete the object. If thread A is the
one that deletes the object, then the destructor will access the object.
If thread B had modified the object prior to dropping its reference,
then unless there is some form of ordering constraint that requires the
modifications on thread B to be visible to thread A prior to the
destructor call then you have a data race and undefined behaviour.

The easiest way to achieve that is to make the fetch_sub use
memory_order_release. This then synchronizes-with the fence with
memory_order_acquire in thread A, and all is well. Making the fence use
memory_order_acq_rel doesn't achieve anything, since this is only
executed in the thread that will call delete (thread A).

Anthony

-- 
Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
just::thread C++11 thread library             http://www.stdthread.co.uk
Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net