1 #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED 2 #define BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED 3 4 #ifndef BOOST_CONFIG_HPP 5 # include <boost/config.hpp> 6 #endif 7 # 8 #if defined(BOOST_HAS_PRAGMA_ONCE) 9 # pragma once 10 #endif 11 12 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. 13 // Copyright 2004-2005 Peter Dimov 14 // Copyright 2007-2012 Ion Gaztanaga 15 // 16 // Distributed under the Boost Software License, Version 1.0. (See 17 // accompanying file LICENSE_1_0.txt or copy at 18 // http://www.boost.org/LICENSE_1_0.txt) 19 // 20 // 21 // Lock-free algorithm by Alexander Terekhov 22 // 23 // Thanks to Ben Hitchings for the #weak + (#shared != 0) 24 // formulation 25 // 26 27 #include <boost/interprocess/detail/config_begin.hpp> 28 #include <boost/interprocess/detail/workaround.hpp> 29 30 #include <boost/interprocess/detail/atomic.hpp> 31 #include <typeinfo> 32 33 namespace boost { 34 35 namespace interprocess { 36 37 namespace ipcdetail { 38 39 class sp_counted_base 40 { 41 private: 42 43 sp_counted_base( sp_counted_base const & ); 44 sp_counted_base & operator= ( sp_counted_base const & ); 45 46 boost::uint32_t use_count_; // #shared 47 boost::uint32_t weak_count_; // #weak + (#shared != 0) 48 49 public: 50 sp_counted_base()51 sp_counted_base(): use_count_( 1 ), weak_count_( 1 ) 52 {} 53 ~sp_counted_base()54 ~sp_counted_base() // nothrow 55 {} 56 add_ref_copy()57 void add_ref_copy() 58 { 59 ipcdetail::atomic_inc32( &use_count_ ); 60 } 61 add_ref_lock()62 bool add_ref_lock() // true on success 63 { 64 for( ;; ) 65 { 66 boost::uint32_t tmp = static_cast< boost::uint32_t const volatile& >( use_count_ ); 67 if( tmp == 0 ) return false; 68 if( ipcdetail::atomic_cas32( &use_count_, tmp + 1, tmp ) == tmp ) 69 return true; 70 } 71 } 72 ref_release()73 bool ref_release() // nothrow 74 { return 1 == ipcdetail::atomic_dec32( &use_count_ ); } 75 weak_add_ref()76 void weak_add_ref() // nothrow 77 { ipcdetail::atomic_inc32( &weak_count_ ); } 78 weak_release()79 bool weak_release() // nothrow 80 { return 1 == ipcdetail::atomic_dec32( &weak_count_ ); } 81 use_count() const82 long use_count() const // nothrow 83 { return (long)static_cast<boost::uint32_t const volatile &>( use_count_ ); } 84 }; 85 86 } // namespace ipcdetail 87 88 } // namespace interprocess 89 90 } // namespace boost 91 92 #include <boost/interprocess/detail/config_end.hpp> 93 94 #endif // #ifndef BOOST_INTERPROCESS_DETAIL_SP_COUNTED_BASE_ATOMIC_HPP_INCLUDED 95