00001 #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED 00002 #define BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED 00003 00004 // 00005 // boost/detail/atomic_count_gcc_x86.hpp 00006 // 00007 // atomic_count for g++ on 486+/AMD64 00008 // 00009 // Copyright 2007 Peter Dimov 00010 // 00011 // Distributed under the Boost Software License, Version 1.0. (See 00012 // accompanying file LICENSE_1_0.txt or copy at 00013 // http://www.boost.org/LICENSE_1_0.txt) 00014 // 00015 00016 namespace boost 00017 { 00018 00019 namespace detail 00020 { 00021 00022 class atomic_count 00023 { 00024 public: 00025 00026 explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {} 00027 00028 long operator++() 00029 { 00030 return atomic_exchange_and_add( &value_, +1 ) + 1; 00031 } 00032 00033 long operator--() 00034 { 00035 return atomic_exchange_and_add( &value_, -1 ) - 1; 00036 } 00037 00038 operator long() const 00039 { 00040 return atomic_exchange_and_add( &value_, 0 ); 00041 } 00042 00043 private: 00044 00045 atomic_count(atomic_count const &); 00046 atomic_count & operator=(atomic_count const &); 00047 00048 mutable int value_; 00049 00050 private: 00051 00052 static int atomic_exchange_and_add( int * pw, int dv ) 00053 { 00054 // int r = *pw; 00055 // *pw += dv; 00056 // return r; 00057 00058 int r; 00059 00060 __asm__ __volatile__ 00061 ( 00062 "lock\n\t" 00063 "xadd %1, %0": 00064 "+m"( *pw ), "=r"( r ): // outputs (%0, %1) 00065 "1"( dv ): // inputs (%2 == %1) 00066 "memory", "cc" // clobbers 00067 ); 00068 00069 return r; 00070 } 00071 }; 00072 00073 } // namespace detail 00074 00075 } // namespace boost 00076 00077 #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED