Chris@16
|
1 #ifndef BOOST_ATOMIC_DETAIL_INTERLOCKED_HPP
|
Chris@16
|
2 #define BOOST_ATOMIC_DETAIL_INTERLOCKED_HPP
|
Chris@16
|
3
|
Chris@16
|
4 // Copyright (c) 2009 Helge Bahmann
|
Chris@16
|
5 // Copyright (c) 2012, 2013 Andrey Semashev
|
Chris@16
|
6 //
|
Chris@16
|
7 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
8 // See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
9 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/atomic/detail/config.hpp>
|
Chris@16
|
12
|
Chris@16
|
13 #ifdef BOOST_HAS_PRAGMA_ONCE
|
Chris@16
|
14 #pragma once
|
Chris@16
|
15 #endif
|
Chris@16
|
16
|
Chris@16
|
17 #if defined(_WIN32_WCE) || (defined(_MSC_VER) && _MSC_VER < 1400)
|
Chris@16
|
18
|
Chris@16
|
19 #include <boost/detail/interlocked.hpp>
|
Chris@16
|
20
|
Chris@16
|
21 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest), exchange, compare)
|
Chris@16
|
22 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) BOOST_INTERLOCKED_EXCHANGE((long*)(dest), newval)
|
Chris@16
|
23 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) BOOST_INTERLOCKED_EXCHANGE_ADD((long*)(dest), addend)
|
Chris@16
|
24 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare)
|
Chris@16
|
25 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) BOOST_INTERLOCKED_EXCHANGE_POINTER(dest, newval)
|
Chris@16
|
26 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_INTERLOCKED_EXCHANGE_ADD((long*)(dest), byte_offset))
|
Chris@16
|
27
|
Chris@16
|
28 #elif defined(_MSC_VER) && _MSC_VER >= 1400
|
Chris@16
|
29
|
Chris@16
|
30 #include <intrin.h>
|
Chris@16
|
31
|
Chris@16
|
32 #pragma intrinsic(_InterlockedCompareExchange)
|
Chris@16
|
33 #pragma intrinsic(_InterlockedExchangeAdd)
|
Chris@16
|
34 #pragma intrinsic(_InterlockedExchange)
|
Chris@16
|
35 #pragma intrinsic(_InterlockedAnd)
|
Chris@16
|
36 #pragma intrinsic(_InterlockedOr)
|
Chris@16
|
37 #pragma intrinsic(_InterlockedXor)
|
Chris@16
|
38
|
Chris@16
|
39 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) _InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare))
|
Chris@16
|
40 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) _InterlockedExchangeAdd((long*)(dest), (long)(addend))
|
Chris@16
|
41 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) _InterlockedExchange((long*)(dest), (long)(newval))
|
Chris@16
|
42 #define BOOST_ATOMIC_INTERLOCKED_AND(dest, arg) _InterlockedAnd((long*)(dest), (long)(arg))
|
Chris@16
|
43 #define BOOST_ATOMIC_INTERLOCKED_OR(dest, arg) _InterlockedOr((long*)(dest), (long)(arg))
|
Chris@16
|
44 #define BOOST_ATOMIC_INTERLOCKED_XOR(dest, arg) _InterlockedXor((long*)(dest), (long)(arg))
|
Chris@16
|
45
|
Chris@16
|
46 #if (defined(_M_IX86) && _M_IX86 >= 500) || defined(_M_AMD64) || defined(_M_IA64)
|
Chris@16
|
47 #pragma intrinsic(_InterlockedCompareExchange64)
|
Chris@16
|
48 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
|
Chris@16
|
49 #endif
|
Chris@16
|
50
|
Chris@16
|
51 #if _MSC_VER >= 1600
|
Chris@16
|
52
|
Chris@16
|
53 // MSVC 2010 and later provide intrinsics for 8 and 16 bit integers.
|
Chris@16
|
54 // Note that for each bit count these macros must be either all defined or all not defined.
|
Chris@16
|
55 // Otherwise atomic<> operations will be implemented inconsistently.
|
Chris@16
|
56
|
Chris@16
|
57 #pragma intrinsic(_InterlockedCompareExchange8)
|
Chris@16
|
58 #pragma intrinsic(_InterlockedExchangeAdd8)
|
Chris@16
|
59 #pragma intrinsic(_InterlockedExchange8)
|
Chris@16
|
60 #pragma intrinsic(_InterlockedAnd8)
|
Chris@16
|
61 #pragma intrinsic(_InterlockedOr8)
|
Chris@16
|
62 #pragma intrinsic(_InterlockedXor8)
|
Chris@16
|
63
|
Chris@16
|
64 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8(dest, exchange, compare) _InterlockedCompareExchange8((char*)(dest), (char)(exchange), (char)(compare))
|
Chris@16
|
65 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD8(dest, addend) _InterlockedExchangeAdd8((char*)(dest), (char)(addend))
|
Chris@16
|
66 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE8(dest, newval) _InterlockedExchange8((char*)(dest), (char)(newval))
|
Chris@16
|
67 #define BOOST_ATOMIC_INTERLOCKED_AND8(dest, arg) _InterlockedAnd8((char*)(dest), (char)(arg))
|
Chris@16
|
68 #define BOOST_ATOMIC_INTERLOCKED_OR8(dest, arg) _InterlockedOr8((char*)(dest), (char)(arg))
|
Chris@16
|
69 #define BOOST_ATOMIC_INTERLOCKED_XOR8(dest, arg) _InterlockedXor8((char*)(dest), (char)(arg))
|
Chris@16
|
70
|
Chris@16
|
71 #pragma intrinsic(_InterlockedCompareExchange16)
|
Chris@16
|
72 #pragma intrinsic(_InterlockedExchangeAdd16)
|
Chris@16
|
73 #pragma intrinsic(_InterlockedExchange16)
|
Chris@16
|
74 #pragma intrinsic(_InterlockedAnd16)
|
Chris@16
|
75 #pragma intrinsic(_InterlockedOr16)
|
Chris@16
|
76 #pragma intrinsic(_InterlockedXor16)
|
Chris@16
|
77
|
Chris@16
|
78 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16(dest, exchange, compare) _InterlockedCompareExchange16((short*)(dest), (short)(exchange), (short)(compare))
|
Chris@16
|
79 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD16(dest, addend) _InterlockedExchangeAdd16((short*)(dest), (short)(addend))
|
Chris@16
|
80 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE16(dest, newval) _InterlockedExchange16((short*)(dest), (short)(newval))
|
Chris@16
|
81 #define BOOST_ATOMIC_INTERLOCKED_AND16(dest, arg) _InterlockedAnd16((short*)(dest), (short)(arg))
|
Chris@16
|
82 #define BOOST_ATOMIC_INTERLOCKED_OR16(dest, arg) _InterlockedOr16((short*)(dest), (short)(arg))
|
Chris@16
|
83 #define BOOST_ATOMIC_INTERLOCKED_XOR16(dest, arg) _InterlockedXor16((short*)(dest), (short)(arg))
|
Chris@16
|
84
|
Chris@16
|
85 #endif // _MSC_VER >= 1600
|
Chris@16
|
86
|
Chris@16
|
87 #if defined(_M_AMD64) || defined(_M_IA64)
|
Chris@16
|
88
|
Chris@16
|
89 #pragma intrinsic(_InterlockedExchangeAdd64)
|
Chris@16
|
90 #pragma intrinsic(_InterlockedExchange64)
|
Chris@16
|
91 #pragma intrinsic(_InterlockedAnd64)
|
Chris@16
|
92 #pragma intrinsic(_InterlockedOr64)
|
Chris@16
|
93 #pragma intrinsic(_InterlockedXor64)
|
Chris@16
|
94
|
Chris@16
|
95 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) _InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend))
|
Chris@16
|
96 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval))
|
Chris@16
|
97 #define BOOST_ATOMIC_INTERLOCKED_AND64(dest, arg) _InterlockedAnd64((__int64*)(dest), (__int64)(arg))
|
Chris@16
|
98 #define BOOST_ATOMIC_INTERLOCKED_OR64(dest, arg) _InterlockedOr64((__int64*)(dest), (__int64)(arg))
|
Chris@16
|
99 #define BOOST_ATOMIC_INTERLOCKED_XOR64(dest, arg) _InterlockedXor64((__int64*)(dest), (__int64)(arg))
|
Chris@16
|
100
|
Chris@16
|
101 #pragma intrinsic(_InterlockedCompareExchangePointer)
|
Chris@16
|
102 #pragma intrinsic(_InterlockedExchangePointer)
|
Chris@16
|
103
|
Chris@16
|
104 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) _InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare))
|
Chris@16
|
105 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) _InterlockedExchangePointer((void**)(dest), (void*)(newval))
|
Chris@16
|
106 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64((long*)(dest), byte_offset))
|
Chris@16
|
107
|
Chris@16
|
108 #else // defined(_M_AMD64) || defined(_M_IA64)
|
Chris@16
|
109
|
Chris@16
|
110 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)_InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare)))
|
Chris@16
|
111 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)_InterlockedExchange((long*)(dest), (long)(newval)))
|
Chris@16
|
112 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD((long*)(dest), byte_offset))
|
Chris@16
|
113
|
Chris@16
|
114 #endif // defined(_M_AMD64) || defined(_M_IA64)
|
Chris@16
|
115
|
Chris@16
|
116 #else // defined(_MSC_VER) && _MSC_VER >= 1400
|
Chris@16
|
117
|
Chris@16
|
118 #if defined(BOOST_USE_WINDOWS_H)
|
Chris@16
|
119
|
Chris@16
|
120 #include <windows.h>
|
Chris@16
|
121
|
Chris@16
|
122 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare))
|
Chris@16
|
123 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) InterlockedExchange((long*)(dest), (long)(newval))
|
Chris@16
|
124 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) InterlockedExchangeAdd((long*)(dest), (long)(addend))
|
Chris@16
|
125
|
Chris@16
|
126 #if defined(_WIN64)
|
Chris@16
|
127
|
Chris@16
|
128 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
|
Chris@16
|
129 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) InterlockedExchange64((__int64*)(dest), (__int64)(newval))
|
Chris@16
|
130 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend))
|
Chris@16
|
131
|
Chris@16
|
132 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare))
|
Chris@16
|
133 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) InterlockedExchangePointer((void**)(dest), (void*)(newval))
|
Chris@16
|
134 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, byte_offset))
|
Chris@16
|
135
|
Chris@16
|
136 #else // defined(_WIN64)
|
Chris@16
|
137
|
Chris@16
|
138 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare))
|
Chris@16
|
139 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval))
|
Chris@16
|
140 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, byte_offset))
|
Chris@16
|
141
|
Chris@16
|
142 #endif // defined(_WIN64)
|
Chris@16
|
143
|
Chris@16
|
144 #else // defined(BOOST_USE_WINDOWS_H)
|
Chris@16
|
145
|
Chris@16
|
146 #if defined(__MINGW64__)
|
Chris@16
|
147 #define BOOST_ATOMIC_INTERLOCKED_IMPORT
|
Chris@16
|
148 #else
|
Chris@16
|
149 #define BOOST_ATOMIC_INTERLOCKED_IMPORT __declspec(dllimport)
|
Chris@16
|
150 #endif
|
Chris@16
|
151
|
Chris@16
|
152 namespace boost {
|
Chris@16
|
153 namespace atomics {
|
Chris@16
|
154 namespace detail {
|
Chris@16
|
155
|
Chris@16
|
156 extern "C" {
|
Chris@16
|
157
|
Chris@16
|
158 BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedCompareExchange(long volatile*, long, long);
|
Chris@16
|
159 BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedExchange(long volatile*, long);
|
Chris@16
|
160 BOOST_ATOMIC_INTERLOCKED_IMPORT long __stdcall InterlockedExchangeAdd(long volatile*, long);
|
Chris@16
|
161
|
Chris@16
|
162 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchange((long*)(dest), (long)(exchange), (long)(compare))
|
Chris@16
|
163 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval) boost::atomics::detail::InterlockedExchange((long*)(dest), (long)(newval))
|
Chris@16
|
164 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, addend) boost::atomics::detail::InterlockedExchangeAdd((long*)(dest), (long)(addend))
|
Chris@16
|
165
|
Chris@16
|
166 #if defined(_WIN64)
|
Chris@16
|
167
|
Chris@16
|
168 BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedCompareExchange64(__int64 volatile*, __int64, __int64);
|
Chris@16
|
169 BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedExchange64(__int64 volatile*, __int64);
|
Chris@16
|
170 BOOST_ATOMIC_INTERLOCKED_IMPORT __int64 __stdcall InterlockedExchangeAdd64(__int64 volatile*, __int64);
|
Chris@16
|
171
|
Chris@16
|
172 BOOST_ATOMIC_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer(void* volatile *, void*, void*);
|
Chris@16
|
173 BOOST_ATOMIC_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer(void* volatile *, void*);
|
Chris@16
|
174
|
Chris@16
|
175 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
|
Chris@16
|
176 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) boost::atomics::detail::InterlockedExchange64((__int64*)(dest), (__int64)(newval))
|
Chris@16
|
177 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) boost::atomics::detail::InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend))
|
Chris@16
|
178
|
Chris@16
|
179 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) boost::atomics::detail::InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare))
|
Chris@16
|
180 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) boost::atomics::detail::InterlockedExchangePointer((void**)(dest), (void*)(newval))
|
Chris@16
|
181 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, byte_offset))
|
Chris@16
|
182
|
Chris@16
|
183 #else // defined(_WIN64)
|
Chris@16
|
184
|
Chris@16
|
185 #define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) ((void*)BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare))
|
Chris@16
|
186 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_POINTER(dest, newval) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE(dest, newval))
|
Chris@16
|
187 #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD_POINTER(dest, byte_offset) ((void*)BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD(dest, byte_offset))
|
Chris@16
|
188
|
Chris@16
|
189 #endif // defined(_WIN64)
|
Chris@16
|
190
|
Chris@16
|
191 } // extern "C"
|
Chris@16
|
192
|
Chris@16
|
193 } // namespace detail
|
Chris@16
|
194 } // namespace atomics
|
Chris@16
|
195 } // namespace boost
|
Chris@16
|
196
|
Chris@16
|
197 #undef BOOST_ATOMIC_INTERLOCKED_IMPORT
|
Chris@16
|
198
|
Chris@16
|
199 #endif // defined(BOOST_USE_WINDOWS_H)
|
Chris@16
|
200
|
Chris@16
|
201 #endif // defined(_MSC_VER)
|
Chris@16
|
202
|
Chris@16
|
203 #endif
|