1 // Copyright (C) 2007, 2008, 2009 Tim Blechmann & Thomas Grill
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 // Disclaimer: Not a Boost library.
9 #ifndef BOOST_LOCKFREE_CAS_HPP_INCLUDED
10 #define BOOST_LOCKFREE_CAS_HPP_INCLUDED
12 #include <boost/lockfree/detail/prefix.hpp>
13 #include <boost/interprocess/detail/atomic.hpp>
14 #include <boost/detail/lightweight_mutex.hpp>
15 #include <boost/static_assert.hpp>
17 #include <boost/cstdint.hpp>
19 #include <boost/mpl/map.hpp>
20 #include <boost/mpl/at.hpp>
21 #include <boost/mpl/if.hpp>
22 #include <boost/mpl/long.hpp>
25 #include "emmintrin.h"
33 inline void memory_barrier(void)
37 #elif defined(__GNUC__) && ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && \
38 (__GNUC_MINOR__ >= 1))) \
39 || defined(__INTEL_COMPILER)
41 #elif defined(_MSC_VER) && (_MSC_VER >= 1300)
43 #elif defined(__APPLE__)
45 #elif defined(__GNUC__) && defined (__i386__)
46 asm volatile("lock; addl $0,0(%%esp)":::"memory");
47 #elif defined(AO_HAVE_nop_full)
50 # warning "no memory barrier implemented for this platform"
54 inline void read_memory_barrier(void)
64 struct atomic_cas_emulator
66 static inline bool cas(volatile C
* addr
, C old
, C nw
)
68 static boost::detail::lightweight_mutex guard
;
69 boost::detail::lightweight_mutex::scoped_lock
lock(guard
);
71 C
* address
= (C
*) addr
;
87 inline bool atomic_cas_emulation(volatile C
* addr
, C old
, C nw
)
89 return atomic_cas_emulator
<C
>::cas(addr
, old
, nw
);
92 using boost::uint32_t;
93 using boost::uint64_t;
97 static inline bool cas(volatile uint32_t * addr
,
101 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || defined(__INTEL_COMPILER)
102 return __sync_bool_compare_and_swap(addr
, old
, nw
);
103 #elif defined(__APPLE__)
104 return OSAtomicCompareAndSwap32Barrier(old
, nw
, addr
);
106 return boost::interprocess::detail::atomic_cas32(addr
, nw
, old
) == old
;
109 typedef uint32_t cas_type
;
111 static const bool is_lockfree
= true;
116 typedef uint64_t cas_type
;
118 static inline bool cas(volatile uint64_t * addr
,
119 uint64_t const & old
,
122 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || \
123 (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 1) \
124 || ((__GNUC__ == 4) && (__GNUC_MINOR__ == 1)))) && (defined(__x86_64__) || defined(__alpha__) ) ) \
125 || defined(__INTEL_COMPILER)
126 return __sync_bool_compare_and_swap(addr
, old
, nw
);
127 #elif defined(_M_IX86)
128 return InterlockedCompareExchange64(reinterpret_cast<volatile LONGLONG
*>(addr
),
129 reinterpret_cast<LONGLONG
>(nw
),
130 reinterpret_cast<LONGLONG
>(old
)) == old
;
131 #elif defined(_M_X64)
132 return InterlockedCompareExchange64(reinterpret_cast<volatile LONGLONG
*>(addr
),
133 reinterpret_cast<LONGLONG
>(nw
),
134 reinterpret_cast<LONGLONG
>(old
)) == old
;
135 #elif defined(__APPLE__)
136 return OSAtomicCompareAndSwap64Barrier(old
, nw
, addr
);
139 return atomic_cas_emulation((uint64_t *)addr
, old
, nw
);
145 static const bool is_lockfree
= false;
147 static const bool is_lockfree
= true;
153 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
154 typedef int cas_type
__attribute__ ((mode (TI
)));
158 bool operator==(cas_type
const & rhs
)
160 return (data
[0] == rhs
.data
[0]) &&
161 (data
[1] == rhs
.data
[1]);
168 static inline bool cas(volatile cas_type
* addr
, cas_type
const & old
, cas_type
const & nw
)
170 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
171 return __sync_bool_compare_and_swap_16(addr
, old
, nw
);
174 return atomic_cas_emulation((cas_type
*)addr
, old
, nw
);
180 static const bool is_lockfree
= false;
182 static const bool is_lockfree
= true;
188 using namespace boost::mpl
;
194 typedef map3
<pair
<long_
<4>, atomic_cas32
>,
195 pair
<long_
<8>, atomic_cas64
>,
196 pair
<long_
<16>, atomic_cas128
>
199 typedef typename at
<cas_map
, long_
<sizeof(C
)> >::type atomic_cas_t
;
201 typedef typename if_
<has_key
<cas_map
, long_
<sizeof(C
)> >,
203 atomic_cas_emulator
<C
> >::type cas_t
;
205 typedef typename
cas_t::cas_type cas_value_t
;
208 static inline bool cas(volatile C
* addr
, C
const & old
, C
const & nw
)
210 return cas_t::cas((volatile cas_value_t
*)addr
,
215 static const bool is_lockfree
= cas_t::is_lockfree
;
218 } /* namespace detail */
220 using detail::atomic_cas
;
222 template <typename C
>
223 inline bool cas(volatile C
* addr
, C
const & old
, C
const & nw
)
225 return atomic_cas
<C
>::cas(addr
, old
, nw
);
228 } /* namespace lockfree */
229 } /* namespace boost */
231 #endif /* BOOST_LOCKFREE_CAS_HPP_INCLUDED */