Add a spinlock to atomic_shared_ptr

This commit is contained in:
Peter Dimov
2017-06-17 23:37:18 +03:00
parent e462f17c2d
commit 67d897a533
2 changed files with 58 additions and 32 deletions

View File

@@ -36,7 +36,7 @@ namespace boost {
public:
atomic_shared_ptr() noexcept = default;
constexpr atomic_shared_ptr( shared_ptr<T> p ) noexcept;
atomic_shared_ptr( shared_ptr<T> p ) noexcept;
atomic_shared_ptr& operator=( shared_ptr<T> r ) noexcept;
@@ -65,7 +65,7 @@ namespace boost {
## Members
```
constexpr atomic_shared_ptr( shared_ptr<T> p ) noexcept;
atomic_shared_ptr( shared_ptr<T> p ) noexcept;
```
[none]
* {blank}

View File

@@ -14,6 +14,8 @@
//
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/detail/spinlock.hpp>
#include <cstring>
namespace boost
{
@@ -24,35 +26,59 @@ private:
boost::shared_ptr<T> p_;
mutable boost::detail::spinlock l_;
atomic_shared_ptr(const atomic_shared_ptr&);
atomic_shared_ptr& operator=(const atomic_shared_ptr&);
private:
bool compare_exchange( shared_ptr<T>& v, shared_ptr<T> w ) BOOST_SP_NOEXCEPT
{
l_.lock();
if( p_._internal_equiv( v ) )
{
p_.swap( w );
l_.unlock();
return true;
}
else
{
shared_ptr<T> tmp( p_ );
l_.unlock();
tmp.swap( v );
return false;
}
}
public:
atomic_shared_ptr() BOOST_SP_NOEXCEPT
{
boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
std::memcpy( &l_, &init, sizeof( init ) );
}
BOOST_CONSTEXPR atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
atomic_shared_ptr( shared_ptr<T> p ) BOOST_SP_NOEXCEPT
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
: p_( std::move( p ) )
#else
: p_( p )
#endif
{
boost::detail::spinlock init = BOOST_DETAIL_SPINLOCK_INIT;
std::memcpy( &l_, &init, sizeof( init ) );
}
atomic_shared_ptr& operator=( shared_ptr<T> r ) BOOST_SP_NOEXCEPT
{
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
atomic_store( &p_, std::move( r ) );
#else
atomic_store( &p_, r );
#endif
return *this;
}
@@ -63,80 +89,80 @@ public:
shared_ptr<T> load( int = 0 ) const BOOST_SP_NOEXCEPT
{
return atomic_load( &p_ );
boost::detail::spinlock::scoped_lock lock( l_ );
return p_;
}
operator shared_ptr<T>() const BOOST_SP_NOEXCEPT
{
return atomic_load( &p_ );
boost::detail::spinlock::scoped_lock lock( l_ );
return p_;
}
void store( shared_ptr<T> r, int = 0 ) BOOST_SP_NOEXCEPT
{
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
atomic_store( &p_, std::move( r ) );
#else
atomic_store( &p_, r );
#endif
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
}
shared_ptr<T> exchange( shared_ptr<T> r, int = 0 ) BOOST_SP_NOEXCEPT
{
{
boost::detail::spinlock::scoped_lock lock( l_ );
p_.swap( r );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
return atomic_exchange( &p_, std::move( r ) );
return std::move( r );
#else
return atomic_exchange( &p_, r );
return r;
#endif
}
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) BOOST_SP_NOEXCEPT
{
return atomic_compare_exchange( &p_, &v, w );
return compare_exchange( v, w );
}
bool compare_exchange_weak( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) BOOST_SP_NOEXCEPT
{
return atomic_compare_exchange( &p_, &v, w );
return compare_exchange( v, w );
}
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int, int ) BOOST_SP_NOEXCEPT
{
return atomic_compare_exchange( &p_, &v, w );
return compare_exchange( v, w );
}
bool compare_exchange_strong( shared_ptr<T>& v, const shared_ptr<T>& w, int = 0 ) BOOST_SP_NOEXCEPT
{
return atomic_compare_exchange( &p_, &v, w );
return compare_exchange( v, w );
}
#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) BOOST_SP_NOEXCEPT
{
return atomic_compare_exchange( &p_, &v, std::move( w ) );
return compare_exchange( v, std::move( w ) );
}
bool compare_exchange_weak( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) BOOST_SP_NOEXCEPT
{
return atomic_compare_exchange( &p_, &v, std::move( w ) );
return compare_exchange( v, std::move( w ) );
}
bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int, int ) BOOST_SP_NOEXCEPT
{
return atomic_compare_exchange( &p_, &v, std::move( w ) );
return compare_exchange( v, std::move( w ) );
}
bool compare_exchange_strong( shared_ptr<T>& v, shared_ptr<T>&& w, int = 0 ) BOOST_SP_NOEXCEPT
{
return atomic_compare_exchange( &p_, &v, std::move( w ) );
return compare_exchange( v, std::move( w ) );
}
#endif