Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / smart_ptr / detail / atomic_count.hpp
index cc44ac2..8aefd44 100644 (file)
 //  boost/detail/atomic_count.hpp - thread/SMP safe reference counter
 //
 //  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
+//  Copyright (c) 2013 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)
+//  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
 //
 //  typedef <implementation-defined> boost::detail::atomic_count;
 //
 //  a;
 //
 //    Returns: (long) the current value of a
+//    Memory Ordering: acquire
 //
 //  ++a;
 //
 //    Effects: Atomically increments the value of a
 //    Returns: (long) the new value of a
+//    Memory Ordering: acquire/release
 //
 //  --a;
 //
 //    Effects: Atomically decrements the value of a
 //    Returns: (long) the new value of a
-//
-//    Important note: when --a returns zero, it must act as a
-//      read memory barrier (RMB); i.e. the calling thread must
-//      have a synchronized view of the memory
-//
-//    On Intel IA-32 (x86) memory is always synchronized, so this
-//      is not a problem.
-//
-//    On many architectures the atomic instructions already act as
-//      a memory barrier.
-//
-//    This property is necessary for proper reference counting, since
-//      a thread can update the contents of a shared object, then
-//      release its reference, and another thread may immediately
-//      release the last reference causing object destruction.
-//
-//    The destructor needs to have a synchronized view of the
-//      object to perform proper cleanup.
-//
-//    Original example by Alexander Terekhov:
-//
-//    Given:
-//
-//    - a mutable shared object OBJ;
-//    - two threads THREAD1 and THREAD2 each holding 
-//      a private smart_ptr object pointing to that OBJ.
-//
-//    t1: THREAD1 updates OBJ (thread-safe via some synchronization)
-//      and a few cycles later (after "unlock") destroys smart_ptr;
-//
-//    t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization 
-//      with respect to shared mutable object OBJ; OBJ destructors
-//      are called driven by smart_ptr interface...
+//    Memory Ordering: acquire/release
 //
 
 #include <boost/config.hpp>
 #include <boost/smart_ptr/detail/sp_has_sync.hpp>
 
-#ifndef BOOST_HAS_THREADS
+#if defined( BOOST_AC_DISABLE_THREADS )
+# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 
-namespace boost
-{
+#elif defined( BOOST_AC_USE_STD_ATOMIC )
+# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
 
-namespace detail
-{
+#elif defined( BOOST_AC_USE_SPINLOCK )
+# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
 
-typedef long atomic_count;
+#elif defined( BOOST_AC_USE_PTHREADS )
+# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
 
-}
+#elif defined( BOOST_SP_DISABLE_THREADS )
+# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 
-}
+#elif defined( BOOST_SP_USE_STD_ATOMIC )
+# include <boost/smart_ptr/detail/atomic_count_std_atomic.hpp>
 
-#elif defined(BOOST_AC_USE_PTHREADS)
-#  include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
+#elif defined( BOOST_SP_USE_SPINLOCK )
+# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
 
-#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) )
-#  include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
+#elif defined( BOOST_SP_USE_PTHREADS )
+# include <boost/smart_ptr/detail/atomic_count_pt.hpp>
 
-#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
-#  include <boost/smart_ptr/detail/atomic_count_win32.hpp>
+#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
+# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
+
+#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined( __PATHSCALE__ )
+# include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp>
 
 #elif defined( BOOST_SP_HAS_SYNC )
-#  include <boost/smart_ptr/detail/atomic_count_sync.hpp>
+# include <boost/smart_ptr/detail/atomic_count_sync.hpp>
 
-#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
-#  include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
+#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# include <boost/smart_ptr/detail/atomic_count_win32.hpp>
 
-#elif defined(BOOST_HAS_PTHREADS)
+#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
+# include <boost/smart_ptr/detail/atomic_count_gcc.hpp>
 
-#  define BOOST_AC_USE_PTHREADS
-#  include <boost/smart_ptr/detail/atomic_count_pthreads.hpp>
+#elif !defined( BOOST_HAS_THREADS )
+# include <boost/smart_ptr/detail/atomic_count_nt.hpp>
 
 #else
-
-// Use #define BOOST_DISABLE_THREADS to avoid the error
-#error Unrecognized threading platform
+# include <boost/smart_ptr/detail/atomic_count_spin.hpp>
 
 #endif