00001 #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED 00002 #define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED 00003 00004 // MS compatible compilers support #pragma once 00005 00006 #if defined(_MSC_VER) && (_MSC_VER >= 1020) 00007 # pragma once 00008 #endif 00009 00010 // 00011 // boost/detail/atomic_count.hpp - thread/SMP safe reference counter 00012 // 00013 // Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. 00014 // 00015 // Distributed under the Boost Software License, Version 1.0. (See 00016 // accompanying file LICENSE_1_0.txt or copy at 00017 // http://www.boost.org/LICENSE_1_0.txt) 00018 // 00019 // typedef <implementation-defined> boost::detail::atomic_count; 00020 // 00021 // atomic_count a(n); 00022 // 00023 // (n is convertible to long) 00024 // 00025 // Effects: Constructs an atomic_count with an initial value of n 00026 // 00027 // a; 00028 // 00029 // Returns: (long) the current value of a 00030 // 00031 // ++a; 00032 // 00033 // Effects: Atomically increments the value of a 00034 // Returns: (long) the new value of a 00035 // 00036 // --a; 00037 // 00038 // Effects: Atomically decrements the value of a 00039 // Returns: (long) the new value of a 00040 // 00041 // Important note: when --a returns zero, it must act as a 00042 // read memory barrier (RMB); i.e. the calling thread must 00043 // have a synchronized view of the memory 00044 // 00045 // On Intel IA-32 (x86) memory is always synchronized, so this 00046 // is not a problem. 00047 // 00048 // On many architectures the atomic instructions already act as 00049 // a memory barrier. 00050 // 00051 // This property is necessary for proper reference counting, since 00052 // a thread can update the contents of a shared object, then 00053 // release its reference, and another thread may immediately 00054 // release the last reference causing object destruction. 00055 // 00056 // The destructor needs to have a synchronized view of the 00057 // object to perform proper cleanup. 00058 // 00059 // Original example by Alexander Terekhov: 00060 // 00061 // Given: 00062 // 00063 // - a mutable shared object OBJ; 00064 // - two threads THREAD1 and THREAD2 each holding 00065 // a private smart_ptr object pointing to that OBJ. 00066 // 00067 // t1: THREAD1 updates OBJ (thread-safe via some synchronization) 00068 // and a few cycles later (after "unlock") destroys smart_ptr; 00069 // 00070 // t2: THREAD2 destroys smart_ptr WITHOUT doing any synchronization 00071 // with respect to shared mutable object OBJ; OBJ destructors 00072 // are called driven by smart_ptr interface... 00073 // 00074 00075 #include <boost/config.hpp> 00076 #include <boost/smart_ptr/detail/sp_has_sync.hpp> 00077 00078 #ifndef BOOST_HAS_THREADS 00079 00080 namespace boost 00081 { 00082 00083 namespace detail 00084 { 00085 00086 typedef long atomic_count; 00087 00088 } 00089 00090 } 00091 00092 #elif defined(BOOST_AC_USE_PTHREADS) 00093 # include <boost/smart_ptr/detail/atomic_count_pthreads.hpp> 00094 00095 #elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) 00096 # include <boost/smart_ptr/detail/atomic_count_gcc_x86.hpp> 00097 00098 #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 00099 # include <boost/smart_ptr/detail/atomic_count_win32.hpp> 00100 00101 #elif defined( BOOST_SP_HAS_SYNC ) 00102 # include <boost/smart_ptr/detail/atomic_count_sync.hpp> 00103 00104 #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) 00105 # include <boost/smart_ptr/detail/atomic_count_gcc.hpp> 00106 00107 #elif defined(BOOST_HAS_PTHREADS) 00108 00109 # define BOOST_AC_USE_PTHREADS 00110 # include <boost/smart_ptr/detail/atomic_count_pthreads.hpp> 00111 00112 #else 00113 00114 // Use #define BOOST_DISABLE_THREADS to avoid the error 00115 #error Unrecognized threading platform 00116 00117 #endif 00118 00119 #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_HPP_INCLUDED