8#ifndef INCLUDED_BSLS_ATOMICOPERATIONS_X86_ALL_GCC
9#define INCLUDED_BSLS_ATOMICOPERATIONS_X86_ALL_GCC
54#include <bsls_atomicoperations_default.h>
58#if defined(BSLS_PLATFORM_CPU_X86) \
59 && (defined(BSLS_PLATFORM_CMP_GNU) || defined(BSLS_PLATFORM_CMP_CLANG))
65struct AtomicOperations_X86_ALL_GCC;
66typedef AtomicOperations_X86_ALL_GCC AtomicOperations_Imp;
73struct Atomic_TypeTraits<AtomicOperations_X86_ALL_GCC>
77 volatile int d_value __attribute__((__aligned__(
sizeof(
int))));
82 volatile Types::Int64 d_value
83 __attribute__((__aligned__(
sizeof(Types::Int64))));
88 volatile unsigned int d_value
89 __attribute__((__aligned__(
sizeof(
unsigned int))));
94 volatile Types::Uint64 d_value
95 __attribute__((__aligned__(
sizeof(Types::Uint64))));
100 void *
volatile d_value __attribute__((__aligned__(
sizeof(
void *))));
108struct AtomicOperations_X86_ALL_GCC
109 : AtomicOperations_Default32<AtomicOperations_X86_ALL_GCC>
111 typedef Atomic_TypeTraits<AtomicOperations_X86_ALL_GCC> AtomicTypes;
115 static int getInt(
const AtomicTypes::Int *atomicInt);
117 static void setInt(AtomicTypes::Int *atomicInt,
int value);
119 static void setIntRelease(AtomicTypes::Int *atomicInt,
int value);
121 static int swapInt(AtomicTypes::Int *atomicInt,
int swapValue);
123 static int testAndSwapInt(AtomicTypes::Int *atomicInt,
127 static int addIntNv(AtomicTypes::Int *atomicInt,
int value);
131 static Types::Int64 getInt64(
const AtomicTypes::Int64 *atomicInt);
133 static void setInt64(AtomicTypes::Int64 *atomicInt, Types::Int64 value);
135 static Types::Int64 swapInt64(AtomicTypes::Int64 *atomicInt,
136 Types::Int64 swapValue);
138 static Types::Int64 testAndSwapInt64(AtomicTypes::Int64 *atomicInt,
139 Types::Int64 compareValue,
140 Types::Int64 swapValue);
142 static Types::Int64 addInt64Nv(AtomicTypes::Int64 *atomicInt,
155int AtomicOperations_X86_ALL_GCC::
156 getInt(
const AtomicTypes::Int *atomicInt)
161 " movl %[obj], %[res] \n\t"
163 : [res]
"=r" (result)
164 : [obj]
"m" (*atomicInt)
171void AtomicOperations_X86_ALL_GCC::
172 setInt(AtomicTypes::Int *atomicInt,
int value)
176 " movl %[val], %[obj] \n\t"
179 : [obj]
"=m" (*atomicInt)
184 " movl %[val], %[obj] \n\t"
185 " lock addl $0, 0(%%esp) \n\t"
187 : [obj]
"=m" (*atomicInt)
194void AtomicOperations_X86_ALL_GCC::
195 setIntRelease(AtomicTypes::Int *atomicInt,
int value)
198 " movl %[val], %[obj] \n\t"
200 : [obj]
"=m" (*atomicInt)
206int AtomicOperations_X86_ALL_GCC::
207 swapInt(AtomicTypes::Int *atomicInt,
int swapValue)
210 " lock xchgl %[val], %[obj] \n\t"
212 : [obj]
"=m" (*atomicInt),
213 [val]
"=r" (swapValue)
214 :
"1" (swapValue),
"m" (*atomicInt)
221int AtomicOperations_X86_ALL_GCC::
222 testAndSwapInt(AtomicTypes::Int *atomicInt,
226 return __sync_val_compare_and_swap(&atomicInt->d_value,
232int AtomicOperations_X86_ALL_GCC::
233 addIntNv(AtomicTypes::Int *atomicInt,
int value)
235 return __sync_add_and_fetch(&atomicInt->d_value, value);
240 getInt64(
const AtomicTypes::Int64 *atomicInt)
242#if BSLS_PLATFORM_CMP_VER_MAJOR >= 40300
244 return __sync_val_compare_and_swap(
254 " movl %%ebx, %%eax \n\t"
255 " movl %%ecx, %%edx \n\t"
257 " lock cmpxchg8b %[obj] \n\t"
260 " lock cmpxchg8b (%[obj]) \n\t"
265 : [res]
"=&A" (result)
268 [obj]
"m" (*atomicInt),
270 [obj]
"S" (atomicInt),
278#if defined(BSLS_PLATFORM_CMP_CLANG) && defined(__PIC__)
283 "ecx",
"cc",
"memory");
290void AtomicOperations_X86_ALL_GCC::
291 setInt64(AtomicTypes::Int64 *atomicInt,
Types::Int64 value)
293 swapInt64(atomicInt, value);
298 swapInt64(AtomicTypes::Int64 *atomicInt,
301#if BSLS_PLATFORM_CMP_VER_MAJOR >= 40300
306 oldValue = atomicInt->d_value;
307 }
while (__sync_val_compare_and_swap(&atomicInt->d_value,
318 " movl %[val], %%ebx \n\t"
321 " lock cmpxchg8b %[obj] \n\t"
326 : [res]
"=A" (result),
327 [obj]
"+m" (*atomicInt)
330 [val]
"g" ((
unsigned int) swapValue),
332 [val]
"b" ((
unsigned int) swapValue),
334 "c" ((int) (swapValue >> 32)),
337#if defined(BSLS_PLATFORM_CMP_CLANG) && defined(__PIC__)
350 testAndSwapInt64(AtomicTypes::Int64 *atomicInt,
354#if BSLS_PLATFORM_CMP_VER_MAJOR >= 40300
355 return __sync_val_compare_and_swap(&atomicInt->d_value,
362 " movl %[val], %%ebx \n\t"
364 " lock cmpxchg8b %[obj] \n\t"
368 : [cmp]
"=A" (compareValue),
369 [obj]
"+m" (*atomicInt)
372 [val]
"g" ((
unsigned int) swapValue),
374 [val]
"b" ((
unsigned int) swapValue),
376 "c" ((int) (swapValue >> 32)),
379#if defined(BSLS_PLATFORM_CMP_CLANG) && defined(__PIC__)
392 addInt64Nv(AtomicTypes::Int64 *atomicInt,
395 return __sync_add_and_fetch(&atomicInt->d_value, value);
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlt_iso8601util.h:691
long long Int64
Definition bsls_types.h:132