fixing stuff
[dyninst.git] / dynutil / h / dyn_detail / boost / detail / atomic_count_gcc_x86.hpp
1 #ifndef DYN_DETAIL_BOOST_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED
2 #define DYN_DETAIL_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 dyn_detail
17 {
18
19 namespace boost
20 {
21
22 namespace detail
23 {
24
25 class atomic_count
26 {
27 public:
28
29     explicit atomic_count( long v ) : value_( static_cast< int >( v ) ) {}
30
31     void operator++()
32     {
33         __asm__
34         (
35             "lock\n\t"
36             "incl %0":
37             "+m"( value_ ): // output (%0)
38             : // inputs
39             "cc" // clobbers
40         );
41     }
42
43     long operator--()
44     {
45         return atomic_exchange_and_add( &value_, -1 ) - 1;
46     }
47
48     operator long() const
49     {
50         return atomic_exchange_and_add( &value_, 0 );
51     }
52
53 private:
54
55     atomic_count(atomic_count const &);
56     atomic_count & operator=(atomic_count const &);
57
58     mutable int value_;
59
60 private:
61
62     static int atomic_exchange_and_add( int * pw, int dv )
63     {
64         // int r = *pw;
65         // *pw += dv;
66         // return r;
67
68         int r;
69
70         __asm__ __volatile__
71         (
72             "lock\n\t"
73             "xadd %1, %0":
74             "+m"( *pw ), "=r"( r ): // outputs (%0, %1)
75             "1"( dv ): // inputs (%2 == %1)
76             "memory", "cc" // clobbers
77         );
78
79         return r;
80     }
81 };
82
83 } // namespace detail
84
85 } // namespace boost
86
87 } // namespace dyn_detail
88
89 #endif // #ifndef DYN_DETAIL_BOOST_DETAIL_ATOMIC_COUNT_SYNC_HPP_INCLUDED