1 | #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED |
2 | #define BOOST_SMART_PTR_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 | long operator++() |
29 | { |
30 | return atomic_exchange_and_add( pw: &value_, dv: +1 ) + 1; |
31 | } |
32 | |
33 | long operator--() |
34 | { |
35 | return atomic_exchange_and_add( pw: &value_, dv: -1 ) - 1; |
36 | } |
37 | |
38 | operator long() const |
39 | { |
40 | return atomic_exchange_and_add( pw: &value_, dv: 0 ); |
41 | } |
42 | |
43 | private: |
44 | |
45 | atomic_count(atomic_count const &); |
46 | atomic_count & operator=(atomic_count const &); |
47 | |
48 | mutable int value_; |
49 | |
50 | private: |
51 | |
52 | static int atomic_exchange_and_add( int * pw, int dv ) |
53 | { |
54 | // int r = *pw; |
55 | // *pw += dv; |
56 | // return r; |
57 | |
58 | int r; |
59 | |
60 | __asm__ __volatile__ |
61 | ( |
62 | "lock\n\t" |
63 | "xadd %1, %0" : |
64 | "+m" ( *pw ), "=r" ( r ): // outputs (%0, %1) |
65 | "1" ( dv ): // inputs (%2 == %1) |
66 | "memory" , "cc" // clobbers |
67 | ); |
68 | |
69 | return r; |
70 | } |
71 | }; |
72 | |
73 | } // namespace detail |
74 | |
75 | } // namespace boost |
76 | |
77 | #endif // #ifndef BOOST_SMART_PTR_DETAIL_ATOMIC_COUNT_GCC_X86_HPP_INCLUDED |
78 | |