williamr@2: #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED williamr@2: #define BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED williamr@2: williamr@2: // MS compatible compilers support #pragma once williamr@2: williamr@2: #if defined(_MSC_VER) && (_MSC_VER >= 1020) williamr@2: # pragma once williamr@2: #endif williamr@2: williamr@2: // williamr@2: // boost/detail/atomic_count.hpp - thread/SMP safe reference counter williamr@2: // williamr@2: // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. williamr@2: // williamr@2: // Distributed under the Boost Software License, Version 1.0. (See williamr@2: // accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: // williamr@2: // typedef boost::detail::atomic_count; williamr@2: // williamr@2: // atomic_count a(n); williamr@2: // williamr@2: // (n is convertible to long) williamr@2: // williamr@2: // Effects: Constructs an atomic_count with an initial value of n williamr@2: // williamr@2: // a; williamr@2: // williamr@2: // Returns: (long) the current value of a williamr@2: // williamr@2: // ++a; williamr@2: // williamr@2: // Effects: Atomically increments the value of a williamr@2: // Returns: nothing williamr@2: // williamr@2: // --a; williamr@2: // williamr@2: // Effects: Atomically decrements the value of a williamr@2: // Returns: (long) zero if the new value of a is zero, williamr@2: // unspecified non-zero value otherwise (usually the new value) williamr@2: // williamr@2: // Important note: when --a returns zero, it must act as a williamr@2: // read memory barrier (RMB); i.e. the calling thread must williamr@2: // have a synchronized view of the memory williamr@2: // williamr@2: // On Intel IA-32 (x86) memory is always synchronized, so this williamr@2: // is not a problem. williamr@2: // williamr@2: // On many architectures the atomic instructions already act as williamr@2: // a memory barrier. williamr@2: // williamr@2: // This property is necessary for proper reference counting, since williamr@2: // a thread can update the contents of a shared object, then williamr@2: // release its reference, and another thread may immediately williamr@2: // release the last reference causing object destruction. williamr@2: // williamr@2: // The destructor needs to have a synchronized view of the williamr@2: // object to perform proper cleanup. williamr@2: // williamr@2: // Original example by Alexander Terekhov: williamr@2: // williamr@2: // Given: williamr@2: // williamr@2: // - a mutable shared object OBJ; williamr@2: // - two threads THREAD1 and THREAD2 each holding williamr@2: // a private smart_ptr object pointing to that OBJ. williamr@2: // williamr@2: // t1: THREAD1 updates OBJ (thread-safe via some synchronization) williamr@2: // and a few cycles later (after "unlock") destroys smart_ptr; williamr@2: // williamr@2: // t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization williamr@2: // with respect to shared mutable object OBJ; OBJ destructors williamr@2: // are called driven by smart_ptr interface... williamr@2: // williamr@2: williamr@2: #include williamr@2: williamr@2: #ifndef BOOST_HAS_THREADS williamr@2: williamr@2: namespace boost williamr@2: { williamr@2: williamr@2: namespace detail williamr@2: { williamr@2: williamr@2: typedef long atomic_count; williamr@2: williamr@2: } williamr@2: williamr@2: } williamr@2: williamr@2: #elif defined(BOOST_AC_USE_PTHREADS) williamr@2: # include williamr@2: #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) williamr@2: # include williamr@2: #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) williamr@2: # include williamr@2: #elif defined(BOOST_HAS_PTHREADS) williamr@2: # define BOOST_AC_USE_PTHREADS williamr@2: # include williamr@2: #else williamr@2: williamr@2: // Use #define BOOST_DISABLE_THREADS to avoid the error williamr@2: #error Unrecognized threading platform williamr@2: williamr@2: #endif williamr@2: williamr@2: #endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_HPP_INCLUDED