Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't the reference counter in boost::shared_ptr volatile?

In the boost::shared_ptr destructor, this is done:

if(--*pn == 0)
{
    boost::checked_delete(px);
    delete pn;
}

where pn is a pointer to the reference counter, which is typedefed as

shared_ptr::count_type -> detail::atomic_count -> long

I would have expected the long to be volatile long, given threaded usage and the non-atomic 0-check-and-deletion in the shared_ptr destructor above. Why isn't it volatile?

EDIT:

It turns out I looked at the header used when multi-threaded usage is not specified (atomic_count.hpp). In atomic_count_win32.hpp, the decrement is properly implemented for multithreaded usage.

like image 933
Johann Gerell Avatar asked Mar 26 '10 11:03

Johann Gerell


1 Answers

Because volatile is not necessary for multithreading, and does nothing beneficial, but potentially destroys a number of optimizations.

In order to ensure safe multithreaded access to a variable, the primitive we need is a memory barrier, which provides both the guarantee of volatile and a few others (it prevents memory access reordering across the barrier, which volatile doesn't do)

I believe shared_ptr uses atomic operations when possible, which implicitly provide a memory barrier. Otherwise it falls back to a mutex, which also provides a memory barrier.

See Why is volatile not considered useful in multithreaded C or C++ programming? or http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/ for more details

Edit
count_type is not a long in the general case. It is convertible to a long. If you look in atomic_count.hpp, the typedef to long is only applied if no threading is available (in which case of course, no synchronization is necessary). Otherwise it uses the implementation defined in boost/smart_ptr/detail/atomic_count_pthreads.hpp or boost/smart_ptr/detail/atomic_count_win32.hpp or one of the other files listed. And those are synchronized wrapper classes that ensures all operations are done atomically.

like image 181
jalf Avatar answered Nov 15 '22 06:11

jalf