This is something I've been meaning to change for years, see http://gcc.gnu.org/ml/libstdc++/2007-10/msg00180.html for a prior post. Currently __shared_ptr<T, _S_single> specializations still dispatch through __gnu_cxx::__exchange_and_add_dispatch for ref-count updates. The attached patch means the _S_single policy is always non-atomic, so that you can get a faster (but not threadsafe!) smart pointer with:
template<typename T> using shared_ptr_unsynchronized = std::__shared_ptr<T, std::_S_single>; This is something I've needed and I've seen others ask about it too e.g. http://stackoverflow.com/q/15129263/981959 http://stackoverflow.com/q/9792668/981959 2013-11-18 Jonathan Wakely <jwakely....@gmail.com> * include/bits/shared_ptr_base.h (_Sp_counted_base<_S_single>): Use non-atomic operations. * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line number. * testsuite/20_util/shared_ptr/cons/void_neg.cc: Likewise. Tested x86_64-linux, with --enable-threads and --disable-threads, committed to trunk.
commit 1f4fcb52da0e14389ffd53bca6dc060a30d180c2 Author: Jonathan Wakely <jwakely....@gmail.com> Date: Mon Nov 18 11:50:19 2013 +0000 * include/bits/shared_ptr_base.h (_Sp_counted_base<_S_single>): Use non-atomic operations. * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line number. * testsuite/20_util/shared_ptr/cons/void_neg.cc: Likewise. diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index cf90d7a..68ccc9e 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -209,11 +209,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Sp_counted_base<_S_single>:: _M_add_ref_lock() { - if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, 1) == 0) - { - _M_use_count = 0; - __throw_bad_weak_ptr(); - } + if (_M_use_count == 0) + __throw_bad_weak_ptr(); + ++_M_use_count; } template<> @@ -248,6 +246,41 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __ATOMIC_RELAXED)); } + template<> + inline void + _Sp_counted_base<_S_single>::_M_add_ref_copy() + { ++_M_use_count; } + + template<> + inline void + _Sp_counted_base<_S_single>::_M_release() noexcept + { + if (--_M_use_count == 0) + { + _M_dispose(); + if (--_M_weak_count == 0) + _M_destroy(); + } + } + + template<> + inline void + _Sp_counted_base<_S_single>::_M_weak_add_ref() noexcept + { ++_M_weak_count; } + + template<> + inline void + _Sp_counted_base<_S_single>::_M_weak_release() noexcept + { + if (--_M_weak_count == 0) + _M_destroy(); + } + + template<> + inline long + _Sp_counted_base<_S_single>::_M_get_use_count() const noexcept + { return _M_use_count; } + // Forward declarations. template<typename _Tp, _Lock_policy _Lp = __default_lock_policy> diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc index db3fcac..01acca5 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc @@ -32,7 +32,7 @@ void test01() { X* px = 0; std::shared_ptr<X> p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 779 } + // { dg-error "incomplete" "" { target *-*-* } 812 } std::shared_ptr<X> p9(ap()); // { dg-error "here" } // { dg-error "incomplete" "" { target *-*-* } 307 } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc index 3fd38cf..5389159 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc @@ -25,5 +25,5 @@ void test01() { std::shared_ptr<void> p((void*)nullptr); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 778 } + // { dg-error "incomplete" "" { target *-*-* } 811 } }