51struct AtomicOperations<1>
53 template <
typename T>
inline
54 static bool LASS_CALL compareAndSwap(
volatile T& dest, T expectedValue, T newValue)
58 "lock; cmpxchgb %2, %0;"
60 :
"=m"(dest),
"=q"(result)
61 :
"q"(newValue),
"a"(expectedValue),
"m"(dest)
66 template <
typename T1,
typename T2>
inline
67 static bool LASS_CALL compareAndSwap(
68 volatile T1& dest1, T1 expected1, T2 expected2, T1 new1, T2 new2)
71#if defined(__PIC__) && LASS_ADDRESS_SIZE == 32
76 "lock; cmpxchgw %%dx, %0;"
79 :
"=m"(dest1),
"=q"(result)
80 :
"a"(expected1),
"d"(expected2),
"m"(new1),
"c"(new2),
"m"(dest1)
86 "lock; cmpxchgw %%dx, %0;"
88 :
"=m"(
reinterpret_cast<volatile num::Tuint16&
>(dest1)),
"=q"(result)
89 :
"a"(expected1),
"d"(new1),
"b"(expected2),
"c"(new2),
90 "m"(
reinterpret_cast<volatile num::Tuint16&
>(dest1))
96 template <
typename T>
inline
97 static void LASS_CALL increment(
volatile T& value)
106 template <
typename T>
inline
107 static void LASS_CALL decrement(
volatile T& value)
109 __asm__ __volatile__(
120struct AtomicOperations<2>
122 template <
typename T>
inline
123 static bool LASS_CALL compareAndSwap(
volatile T& dest, T expectedValue, T newValue)
126 __asm__ __volatile__(
127 "lock; cmpxchgw %2, %0;"
129 :
"=m"(dest),
"=q"(result)
130 :
"q"(newValue),
"a"(expectedValue),
"m"(dest)
135 template <
typename T1,
typename T2>
inline
136 static bool LASS_CALL compareAndSwap(
137 volatile T1& dest1, T1 expected1, T2 expected2, T1 new1, T2 new2)
140 __asm__ __volatile__(
145 "lock; cmpxchgl %%edx, %0;"
147 :
"=m"(
reinterpret_cast<volatile num::Tuint32&
>(dest1)),
"=q"(result)
148 :
"a"(expected2),
"d"(new2),
"g"(expected1),
"g"(new1),
149 "m"(
reinterpret_cast<volatile num::Tuint32&
>(dest1))
154 template <
typename T>
inline
155 static void LASS_CALL increment(
volatile T& value)
157 __asm__ __volatile__(
164 template <
typename T>
inline
165 static void LASS_CALL decrement(
volatile T& value)
167 __asm__ __volatile__(
178struct AtomicOperations<4>
180 template <
typename T>
inline
181 static bool LASS_CALL compareAndSwap(
volatile T& dest, T expectedValue, T newValue)
184 __asm__ __volatile__(
185 "lock; cmpxchgl %2, %0;"
187 :
"=m"(dest),
"=q"(result)
188 :
"q"(newValue),
"a"(expectedValue),
"m"(dest)
193 template <
typename T1,
typename T2>
inline
194 static bool LASS_CALL compareAndSwap(
195 volatile T1& dest1, T1 expected1, T2 expected2, T1 new1, T2 new2)
202#if defined(__PIC__) && LASS_ADDRESS_SIZE == 32
203 __asm__ __volatile__(
206 "lock; cmpxchg8b %0;"
209 :
"=m"(dest1),
"=q"(result)
210 :
"a"(expected1),
"d"(expected2),
"m"(new1),
"c"(new2),
"m"(dest1)
213 __asm__ __volatile__(
214 "lock; cmpxchg8b %0;"
216 :
"=m"(dest1),
"=q"(result)
217 :
"a"(expected1),
"d"(expected2),
"b"(new1),
"c"(new2),
"m"(dest1)
223 template <
typename T>
inline
224 static void LASS_CALL increment(
volatile T& value)
226 __asm__ __volatile__(
233 template <
typename T>
inline
234 static void LASS_CALL decrement(
volatile T& value)
236 __asm__ __volatile__(
247struct AtomicOperations<8>
249 template <
typename T>
inline
250 static bool LASS_CALL compareAndSwap(
volatile T& dest, T expectedValue, T newValue)
253#if LASS_ADDRESS_SIZE == 32
258 __asm__ __volatile__(
260 "movl (%%ecx),%%ebx;"
261 "movl 4(%%ecx),%%ecx;"
262 "lock; cmpxchg8b %0;"
265 :
"=m"(dest),
"=q"(result)
267 "a"(
reinterpret_cast<volatile num::Tuint32*
>((
void*)&expectedValue)[0]),
268 "d"(
reinterpret_cast<volatile num::Tuint32*
>((
void*)&expectedValue)[1]),
272 __asm__ __volatile__(
273 "lock; cmpxchg8b %0;"
275 :
"=m"(dest),
"=q"(result)
277 "a"(
reinterpret_cast<volatile num::Tuint32*
>((
void*)&expectedValue)[0]),
278 "d"(
reinterpret_cast<volatile num::Tuint32*
>((
void*)&expectedValue)[1]),
279 "b"(
reinterpret_cast<volatile num::Tuint32*
>((
void*)&newValue)[0]),
280 "c"(
reinterpret_cast<volatile num::Tuint32*
>((
void*)&newValue)[1])
284 __asm__ __volatile__(
285 "lock; cmpxchgq %2, %0;"
287 :
"=m"(dest),
"=q"(result)
288 :
"q"(newValue),
"a"(expectedValue),
"m"(dest)
294#if LASS_ADDRESS_SIZE != 32
295 template <
typename T1,
typename T2>
inline
296 static bool LASS_CALL compareAndSwap(
297 volatile T1& dest1, T1 expected1, T2 expected2, T1 new1, T2 new2)
299 LASS_ASSERT((
reinterpret_cast<num::Tuint64
>(&dest1) & 0xf) == 0);
301 __asm__ __volatile__(
302 "lock; cmpxchg16b %0;"
304 :
"=m"(dest1),
"=q"(result)
305 :
"a"(expected1),
"d"(expected2),
"b"(new1),
"c"(new2),
"m"(dest1)
311 template <
typename T>
inline
312 static void LASS_CALL increment(
volatile T& value)
314#if LASS_ADDRESS_SIZE == 32
324 __asm__ __volatile__(
332 template <
typename T>
inline
333 static void LASS_CALL decrement(
volatile T& value)
335#if LASS_ADDRESS_SIZE == 32
345 __asm__ __volatile__(
bool atomicCompareAndSwap(volatile T &dest, T expectedValue, T newValue)
Performs the following pseudocode in an atomic way (no other threads can intervene):
general utility, debug facilities, ...
Library for Assembled Shared Sources.