42 #ifndef QATOMIC_ARMV6_H
43 #define QATOMIC_ARMV6_H
49 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
56 #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
63 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
70 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
77 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
86 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
95 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
100 template <
typename T>
106 #ifndef Q_DATA_MEMORY_BARRIER
107 # define Q_DATA_MEMORY_BARRIER asm volatile("":::"memory")
109 #ifndef Q_COMPILER_MEMORY_BARRIER
110 # define Q_COMPILER_MEMORY_BARRIER asm volatile("":::"memory")
115 register int newValue;
118 "ldrex %[newValue], [%[_q_value]]\n"
119 "add %[newValue], %[newValue], #1\n"
120 "strex %[result], %[newValue], [%[_q_value]]\n"
121 "teq %[result], #0\n"
123 : [newValue]
"=&r" (newValue),
124 [result]
"=&r" (result),
128 return newValue != 0;
133 register int newValue;
136 "ldrex %[newValue], [%[_q_value]]\n"
137 "sub %[newValue], %[newValue], #1\n"
138 "strex %[result], %[newValue], [%[_q_value]]\n"
139 "teq %[result], #0\n"
141 : [newValue]
"=&r" (newValue),
142 [result]
"=&r" (result),
146 return newValue != 0;
153 "ldrex %[result], [%[_q_value]]\n"
154 "eors %[result], %[result], %[expectedValue]\n"
156 "strexeq %[result], %[newValue], [%[_q_value]]\n"
157 "teqeq %[result], #1\n"
159 : [result]
"=&r" (result),
161 : [expectedValue]
"r" (expectedValue),
162 [newValue]
"r" (newValue),
170 register int originalValue;
173 "ldrex %[originalValue], [%[_q_value]]\n"
174 "strex %[result], %[newValue], [%[_q_value]]\n"
175 "teq %[result], #0\n"
177 : [originalValue]
"=&r" (originalValue),
178 [result]
"=&r" (result),
180 : [newValue]
"r" (newValue),
183 return originalValue;
188 register int originalValue;
189 register int newValue;
192 "ldrex %[originalValue], [%[_q_value]]\n"
193 "add %[newValue], %[originalValue], %[valueToAdd]\n"
194 "strex %[result], %[newValue], [%[_q_value]]\n"
195 "teq %[result], #0\n"
197 : [originalValue]
"=&r" (originalValue),
198 [newValue]
"=&r" (newValue),
199 [result]
"=&r" (result),
201 : [valueToAdd]
"r" (valueToAdd),
204 return originalValue;
207 template <
typename T>
212 "ldrex %[result], [%[_q_value]]\n"
213 "eors %[result], %[result], %[expectedValue]\n"
215 "strexeq %[result], %[newValue], [%[_q_value]]\n"
216 "teqeq %[result], #1\n"
218 : [result]
"=&r" (result),
220 : [expectedValue]
"r" (expectedValue),
221 [newValue]
"r" (newValue),
222 [_q_value]
"r" (&_q_value)
227 template <
typename T>
230 register T *originalValue;
233 "ldrex %[originalValue], [%[_q_value]]\n"
234 "strex %[result], %[newValue], [%[_q_value]]\n"
235 "teq %[result], #0\n"
237 : [originalValue]
"=&r" (originalValue),
238 [result]
"=&r" (result),
240 : [newValue]
"r" (newValue),
241 [_q_value]
"r" (&_q_value)
243 return originalValue;
246 template <
typename T>
249 register T *originalValue;
250 register T *newValue;
253 "ldrex %[originalValue], [%[_q_value]]\n"
254 "add %[newValue], %[originalValue], %[valueToAdd]\n"
255 "strex %[result], %[newValue], [%[_q_value]]\n"
256 "teq %[result], #0\n"
258 : [originalValue]
"=&r" (originalValue),
259 [newValue]
"=&r" (newValue),
260 [result]
"=&r" (result),
262 : [valueToAdd]
"r" (valueToAdd *
sizeof(T)),
263 [_q_value]
"r" (&_q_value)
265 return originalValue;
276 #if __TARGET_ARCH_THUMB-0 < 4
282 #ifndef Q_DATA_MEMORY_BARRIER
283 # define Q_DATA_MEMORY_BARRIER __schedule_barrier()
285 #ifndef Q_COMPILER_MEMORY_BARRIER
286 # define Q_COMPILER_MEMORY_BARRIER __schedule_barrier()
291 register int newValue;
296 add newValue, newValue, #1
301 return newValue != 0;
306 register int newValue;
311 sub newValue, newValue, #1
316 return newValue != 0;
325 eors result, result, expectedValue
326 strexeq result, newValue, [&
_q_value]
335 register int originalValue;
344 return originalValue;
349 register int originalValue;
350 register int newValue;
355 add newValue, originalValue, valueToAdd
360 return originalValue;
363 template <
typename T>
369 ldrex result, [&_q_value]
370 eors result, result, expectedValue
371 strexeq result, newValue, [&_q_value]
378 template <
typename T>
381 register T *originalValue;
385 ldrex originalValue, [&_q_value]
386 strex result, newValue, [&_q_value]
390 return originalValue;
393 template <
typename T>
396 register T *originalValue;
397 register T *newValue;
401 ldrex originalValue, [&_q_value]
402 add newValue, originalValue, valueToAdd *
sizeof(T)
403 strex result, newValue, [&_q_value]
407 return originalValue;
410 #if __TARGET_ARCH_THUMB-0 < 4
482 template <
typename T>
485 bool returnValue = testAndSetRelaxed(expectedValue, newValue);
490 template <
typename T>
494 return testAndSetRelaxed(expectedValue, newValue);
497 template <
typename T>
501 bool returnValue = testAndSetAcquire(expectedValue, newValue);
506 template <
typename T>
509 T *returnValue = fetchAndStoreRelaxed(newValue);
514 template <
typename T>
518 return fetchAndStoreRelaxed(newValue);
521 template <
typename T>
525 T *returnValue = fetchAndStoreRelaxed(newValue);
530 template <
typename T>
533 T *returnValue = fetchAndAddRelaxed(valueToAdd);
538 template <
typename T>
542 return fetchAndAddRelaxed(valueToAdd);
545 template <
typename T>
549 T *returnValue = fetchAndAddRelaxed(valueToAdd);
554 #undef Q_DATA_MEMORY_BARRIER
555 #undef Q_COMPILER_MEMORY_BARRIER
561 #endif // QATOMIC_ARMV6_H
int fetchAndStoreRelaxed(int newValue)
bool testAndSetRelease(int expectedValue, int newValue)
static bool isFetchAndAddNative()
T * fetchAndAddAcquire(qptrdiff valueToAdd)
T * fetchAndAddOrdered(qptrdiff valueToAdd)
static bool isReferenceCountingNative()
int fetchAndAddRelaxed(int valueToAdd)
T * fetchAndStoreAcquire(T *newValue)
T * fetchAndAddRelease(qptrdiff valueToAdd)
int fetchAndAddAcquire(int valueToAdd)
static bool isReferenceCountingWaitFree()
T * fetchAndAddRelaxed(qptrdiff valueToAdd)
static bool isFetchAndAddNative()
bool testAndSetOrdered(T *expectedValue, T *newValue)
bool testAndSetAcquire(int expectedValue, int newValue)
static bool isFetchAndStoreNative()
#define QT_BEGIN_NAMESPACE
static bool isTestAndSetNative()
static bool isTestAndSetNative()
static bool isFetchAndStoreNative()
T * fetchAndStoreRelaxed(T *newValue)
static bool isFetchAndAddWaitFree()
bool testAndSetRelaxed(int expectedValue, int newValue)
T * fetchAndStoreRelease(T *newValue)
bool testAndSetRelease(T *expectedValue, T *newValue)
static bool isFetchAndStoreWaitFree()
#define Q_COMPILER_MEMORY_BARRIER
static bool isTestAndSetWaitFree()
bool testAndSetAcquire(T *expectedValue, T *newValue)
#define Q_DATA_MEMORY_BARRIER
static bool isFetchAndAddWaitFree()
T * fetchAndStoreOrdered(T *newValue)
static bool isFetchAndStoreWaitFree()
bool testAndSetRelaxed(T *expectedValue, T *newValue)
int fetchAndStoreAcquire(int newValue)
static bool isTestAndSetWaitFree()
bool testAndSetOrdered(int expectedValue, int newValue)
int fetchAndAddOrdered(int valueToAdd)
int fetchAndStoreOrdered(int newValue)
int fetchAndAddRelease(int valueToAdd)
int fetchAndStoreRelease(int newValue)