Boost logo

Boost-Commit :

From: pdimov_at_[hidden]
Date: 2008-04-20 10:59:12


Author: pdimov
Date: 2008-04-20 10:59:12 EDT (Sun, 20 Apr 2008)
New Revision: 44636
URL: http://svn.boost.org/trac/boost/changeset/44636

Log:
Atomic access added.
Added:
   trunk/boost/memory_order.hpp (contents, props changed)
   trunk/libs/smart_ptr/test/sp_atomic_test.cpp (contents, props changed)
Text files modified:
   trunk/boost/shared_ptr.hpp | 64 ++++++++++++++++++++++++++++++++++++++++
   trunk/libs/smart_ptr/test/Jamfile.v2 | 1
   2 files changed, 65 insertions(+), 0 deletions(-)

Added: trunk/boost/memory_order.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/memory_order.hpp 2008-04-20 10:59:12 EDT (Sun, 20 Apr 2008)
@@ -0,0 +1,35 @@
+#ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED
+#define BOOST_MEMORY_ORDER_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// boost/memory_order.hpp
+//
+// Defines enum boost::memory_order per the C++0x working draft
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+namespace boost
+{
+
+enum memory_order
+{
+ memory_order_relaxed = 0,
+ memory_order_acquire = 1,
+ memory_order_release = 2,
+ memory_order_acq_rel = 3, // acquire | release
+ memory_order_seq_cst = 7, // acq_rel | 4
+};
+
+} // namespace boost
+
+#endif // #ifndef BOOST_MEMORY_ORDER_HPP_INCLUDED

Modified: trunk/boost/shared_ptr.hpp
==============================================================================
--- trunk/boost/shared_ptr.hpp (original)
+++ trunk/boost/shared_ptr.hpp 2008-04-20 10:59:12 EDT (Sun, 20 Apr 2008)
@@ -32,6 +32,11 @@
 #include <boost/detail/shared_count.hpp>
 #include <boost/detail/workaround.hpp>
 
+#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
+#include <boost/detail/spinlock_pool.hpp>
+#include <boost/memory_order.hpp>
+#endif
+
 #include <algorithm> // for std::swap
 #include <functional> // for std::less
 #include <typeinfo> // for std::bad_cast
@@ -472,6 +477,65 @@
         return pn.get_deleter( ti );
     }
 
+ // atomic access
+
+#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
+
+ shared_ptr<T> atomic_load( memory_order /*mo*/ = memory_order_seq_cst ) const
+ {
+ boost::detail::spinlock_pool<2>::scoped_lock lock( this );
+ return *this;
+ }
+
+ void atomic_store( shared_ptr<T> r, memory_order /*mo*/ = memory_order_seq_cst )
+ {
+ boost::detail::spinlock_pool<2>::scoped_lock lock( this );
+ swap( r );
+ }
+
+ shared_ptr<T> atomic_swap( shared_ptr<T> r, memory_order /*mo*/ = memory_order_seq_cst )
+ {
+ boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( this );
+
+ sp.lock();
+ swap( r );
+ sp.unlock();
+
+ return r; // return std::move(r)
+ }
+
+ bool atomic_compare_swap( shared_ptr<T> & v, shared_ptr<T> w )
+ {
+ boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( this );
+
+ sp.lock();
+
+ if( px == v.px && pn == v.pn )
+ {
+ swap( w );
+
+ sp.unlock();
+
+ return true;
+ }
+ else
+ {
+ shared_ptr tmp( *this );
+
+ sp.unlock();
+
+ tmp.swap( v );
+ return false;
+ }
+ }
+
+ inline bool atomic_compare_swap( shared_ptr<T> & v, shared_ptr<T> w, memory_order /*success*/, memory_order /*failure*/ )
+ {
+ return atomic_compare_swap( v, w ); // std::move( w )
+ }
+
+#endif
+
 // Tasteless as this may seem, making all members public allows member templates
 // to work in the absence of member template friends. (Matthew Langston)
 

Modified: trunk/libs/smart_ptr/test/Jamfile.v2
==============================================================================
--- trunk/libs/smart_ptr/test/Jamfile.v2 (original)
+++ trunk/libs/smart_ptr/test/Jamfile.v2 2008-04-20 10:59:12 EDT (Sun, 20 Apr 2008)
@@ -44,5 +44,6 @@
           [ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ]
           [ run spinlock_pool_test.cpp ]
           [ run sp_accept_owner_test.cpp ]
+ [ run sp_atomic_test.cpp ]
         ;
 }

Added: trunk/libs/smart_ptr/test/sp_atomic_test.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/smart_ptr/test/sp_atomic_test.cpp 2008-04-20 10:59:12 EDT (Sun, 20 Apr 2008)
@@ -0,0 +1,87 @@
+#include <boost/config.hpp>
+
+// sp_atomic_test.cpp
+//
+// Copyright (c) 2008 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/shared_ptr.hpp>
+
+//
+
+struct X
+{
+};
+
+#define BOOST_TEST_SP_EQ( p, q ) BOOST_TEST( p == q && !( p < q ) && !( q < p ) )
+
+int main()
+{
+ boost::shared_ptr<X> px( new X );
+
+ {
+ boost::shared_ptr<X> p2 = px.atomic_load();
+ BOOST_TEST_SP_EQ( p2, px );
+
+ boost::shared_ptr<X> px2( new X );
+ px.atomic_store( px2 );
+ BOOST_TEST_SP_EQ( px, px2 );
+
+ p2 = px.atomic_load();
+ BOOST_TEST_SP_EQ( p2, px );
+ BOOST_TEST_SP_EQ( p2, px2 );
+
+ boost::shared_ptr<X> px3( new X );
+ boost::shared_ptr<X> p3 = px.atomic_swap( px3 );
+ BOOST_TEST_SP_EQ( p3, px2 );
+ BOOST_TEST_SP_EQ( px, px3 );
+
+ boost::shared_ptr<X> px4( new X );
+ boost::shared_ptr<X> cmp;
+
+ bool r = px.atomic_compare_swap( cmp, px4 );
+ BOOST_TEST( !r );
+ BOOST_TEST_SP_EQ( px, px3 );
+ BOOST_TEST_SP_EQ( cmp, px3 );
+
+ r = px.atomic_compare_swap( cmp, px4 );
+ BOOST_TEST( r );
+ BOOST_TEST_SP_EQ( px, px4 );
+ }
+
+ //
+
+ px.reset();
+
+ {
+ boost::shared_ptr<X> p2 = px.atomic_load( boost::memory_order_acquire );
+ BOOST_TEST_SP_EQ( p2, px );
+
+ boost::shared_ptr<X> px2( new X );
+ px.atomic_store( px2, boost::memory_order_release );
+ BOOST_TEST_SP_EQ( px, px2 );
+
+ boost::shared_ptr<X> p3 = px.atomic_swap( boost::shared_ptr<X>(), boost::memory_order_acq_rel );
+ BOOST_TEST_SP_EQ( p3, px2 );
+ BOOST_TEST_SP_EQ( px, p2 );
+
+ boost::shared_ptr<X> px4( new X );
+ boost::shared_ptr<X> cmp( px2 );
+
+ bool r = px.atomic_compare_swap( cmp, px4, boost::memory_order_acquire, boost::memory_order_relaxed );
+ BOOST_TEST( !r );
+ BOOST_TEST_SP_EQ( px, p2 );
+ BOOST_TEST_SP_EQ( cmp, p2 );
+
+ r = px.atomic_compare_swap( cmp, px4, boost::memory_order_release, boost::memory_order_acquire );
+ BOOST_TEST( r );
+ BOOST_TEST_SP_EQ( px, px4 );
+ }
+
+ return boost::report_errors();
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk