Merge c:/dyninst/pc_bluegene/dyninst into dyn_pc_integration
[dyninst.git] / external / boost / detail / atomic_count_gcc_x86.hpp
1 #ifndef BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
2 #define BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
3
4 //
5 //  boost/detail/atomic_count_gcc_x86.hpp
6 //
7 //  atomic_count for g++ on 486+/AMD64
8 //
9 //  Copyright 2007 Peter Dimov
10 //
11 //  Distributed under the Boost Software License, Version 1.0. (See
12 //  accompanying file LICENSE_1_0.txt or copy at
13 //  http://www.boost.org/LICENSE_1_0.txt)
14 //
15
16 namespace boost
17 {
18
19 namespace detail
20 {
21
22 class atomic_count
23 {
24 public:
25
26     explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {}
27
28     void operator++()
29     {
30         __asm__
31         (
32             "lock\n\t"
33             "incl %0":
34             "+m"( value_ ): // output (%0)
35             : // inputs
36             "cc" // clobbers
37         );
38     }
39
40     long operator--()
41     {
42         return atomic_exchange_and_add( &value_, -1 ) - 1;
43     }
44
45     operator long() const
46     {
47         return atomic_exchange_and_add( &value_, 0 );
48     }
49
50 private:
51
52     atomic_count(atomic_count const &);
53     atomic_count & operator=(atomic_count const &);
54
55     mutable int value_;
56
57 private:
58
59     static int atomic_exchange_and_add( int * pw, int dv )
60     {
61         // int r = *pw;
62         // *pw += dv;
63         // return r;
64
65         int r;
66
67         __asm__ __volatile__
68         (
69             "lock\n\t"
70             "xadd %1, %0":
71             "+m"( *pw ), "=r"( r ): // outputs (%0, %1)
72             "1"( dv ): // inputs (%2 == %1)
73             "memory", "cc" // clobbers
74         );
75
76         return r;
77     }
78 };
79
80 } // namespace detail
81
82 } // namespace boost
83
84 #endif // #ifndef BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED