From 5b57eff9b880698022432c1916cf6c852844734a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 8 May 2007 20:14:38 +0000 Subject: [PATCH] atomic_count_gcc_x86 added since _sync doesn't work on i386 [SVN r37637] --- include/boost/detail/atomic_count.hpp | 14 ++++ include/boost/detail/atomic_count_gcc_x86.hpp | 84 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 include/boost/detail/atomic_count_gcc_x86.hpp diff --git a/include/boost/detail/atomic_count.hpp b/include/boost/detail/atomic_count.hpp index 823b929..804fd1a 100644 --- a/include/boost/detail/atomic_count.hpp +++ b/include/boost/detail/atomic_count.hpp @@ -90,16 +90,30 @@ typedef long atomic_count; } #elif defined(BOOST_AC_USE_PTHREADS) + # include + +#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) + +# include + #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + # include + #elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 ) + # include + #elif defined(__GLIBCPP__) || defined(__GLIBCXX__) + # include + #elif defined(BOOST_HAS_PTHREADS) + # define BOOST_AC_USE_PTHREADS # include + #else // Use #define BOOST_DISABLE_THREADS to avoid the error diff --git a/include/boost/detail/atomic_count_gcc_x86.hpp b/include/boost/detail/atomic_count_gcc_x86.hpp new file mode 100644 index 0000000..1312e8c --- /dev/null +++ b/include/boost/detail/atomic_count_gcc_x86.hpp @@ -0,0 +1,84 @@ +#ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED +#define BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED + +// +// boost/detail/atomic_count_gcc_x86.hpp +// +// atomic_count for g++ on 486+/AMD64 +// +// Copyright 2007 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) +// + +namespace boost +{ + +namespace detail +{ + +class atomic_count +{ +public: + + explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {} + + void operator++() + { + __asm__ + ( + "lock\n\t" + "incl %0": + "+m"( value_ ): // output (%0) + : // inputs + "cc" // clobbers + ); + } + + long operator--() + { + return atomic_exchange_and_add( &value_, -1 ) - 1; + } + + operator long() const + { + return atomic_exchange_and_add( &value_, 0 ); + } + +private: + + atomic_count(atomic_count const &); + atomic_count & operator=(atomic_count const &); + + mutable int value_; + +private: + + static int atomic_exchange_and_add( int * pw, int dv ) + { + // int r = *pw; + // *pw += dv; + // return r; + + int r; + + __asm__ __volatile__ + ( + "lock\n\t" + "xadd %1, %0": + "+m"( *pw ), "=r"( r ): // outputs (%0, %1) + "1"( dv ): // inputs (%2 == %1) + "memory", "cc" // clobbers + ); + + return r; + } +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED