1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QATOMIC_ALPHA_H
43 #define QATOMIC_ALPHA_H
44
45 QT_BEGIN_HEADER
46
47 QT_BEGIN_NAMESPACE
48
49 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
50
isReferenceCountingNative()51 inline bool QBasicAtomicInt::isReferenceCountingNative()
52 { return true; }
isReferenceCountingWaitFree()53 inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
54 { return false; }
55
56 #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
57
isTestAndSetNative()58 inline bool QBasicAtomicInt::isTestAndSetNative()
59 { return true; }
isTestAndSetWaitFree()60 inline bool QBasicAtomicInt::isTestAndSetWaitFree()
61 { return false; }
62
63 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
64
isFetchAndStoreNative()65 inline bool QBasicAtomicInt::isFetchAndStoreNative()
66 { return true; }
isFetchAndStoreWaitFree()67 inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
68 { return false; }
69
70 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
71
isFetchAndAddNative()72 inline bool QBasicAtomicInt::isFetchAndAddNative()
73 { return true; }
isFetchAndAddWaitFree()74 inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
75 { return false; }
76
77 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
78
79 template <typename T>
isTestAndSetNative()80 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative()
81 { return true; }
82 template <typename T>
isTestAndSetWaitFree()83 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree()
84 { return false; }
85
86 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
87
88 template <typename T>
isFetchAndStoreNative()89 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
90 { return true; }
91 template <typename T>
isFetchAndStoreWaitFree()92 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
93 { return false; }
94
95 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
96
97 template <typename T>
isFetchAndAddNative()98 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative()
99 { return true; }
100 template <typename T>
isFetchAndAddWaitFree()101 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
102 { return false; }
103
104 #if defined(Q_CC_GNU)
105
ref()106 inline bool QBasicAtomicInt::ref()
107 {
108 int old, tmp;
109 asm volatile("1:\n"
110 "ldl_l %0,%2\n" /* old=*ptr; */
111 "addl %0,1,%1\n" /* tmp=old+1; */
112 "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
113 "beq %1,2f\n" /* if (tmp == 0) goto 2; */
114 "br 3f\n" /* goto 3; */
115 "2: br 1b\n" /* goto 1; */
116 "3:\n"
117 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
118 :
119 : "memory");
120 return old != -1;
121 }
122
deref()123 inline bool QBasicAtomicInt::deref()
124 {
125 int old, tmp;
126 asm volatile("1:\n"
127 "ldl_l %0,%2\n" /* old=*ptr; */
128 "subl %0,1,%1\n" /* tmp=old-1; */
129 "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
130 "beq %1,2f\n" /* if (tmp==0) goto 2; */
131 "br 3f\n" /* goto 3; */
132 "2: br 1b\n" /* goto 1; */
133 "3:\n"
134 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
135 :
136 : "memory");
137 return old != 1;
138 }
139
testAndSetRelaxed(int expectedValue,int newValue)140 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
141 {
142 int ret;
143 asm volatile("1:\n"
144 "ldl_l %0,%1\n" /* ret=*ptr; */
145 "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
146 "beq %0,3f\n" /* if (ret==0) goto 3; */
147 "mov %3,%0\n" /* ret=newval; */
148 "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
149 "beq %0,2f\n" /* if (ret==0) goto 2; */
150 "br 3f\n" /* goto 3; */
151 "2: br 1b\n" /* goto 1; */
152 "3:\n"
153 : "=&r" (ret), "+m" (_q_value)
154 : "r" (expectedValue), "r" (newValue)
155 : "memory");
156 return ret != 0;
157 }
158
testAndSetAcquire(int expectedValue,int newValue)159 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
160 {
161 int ret;
162 asm volatile("1:\n"
163 "ldl_l %0,%1\n" /* ret=*ptr; */
164 "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
165 "beq %0,3f\n" /* if (ret==0) goto 3; */
166 "mov %3,%0\n" /* ret=newval; */
167 "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
168 "beq %0,2f\n" /* if (ret==0) goto 2; */
169 "br 3f\n" /* goto 3; */
170 "2: br 1b\n" /* goto 1; */
171 "3:\n"
172 "mb\n"
173 : "=&r" (ret), "+m" (_q_value)
174 : "r" (expectedValue), "r" (newValue)
175 : "memory");
176 return ret != 0;
177 }
178
testAndSetRelease(int expectedValue,int newValue)179 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
180 {
181 int ret;
182 asm volatile("mb\n"
183 "1:\n"
184 "ldl_l %0,%1\n" /* ret=*ptr; */
185 "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
186 "beq %0,3f\n" /* if (ret==0) goto 3; */
187 "mov %3,%0\n" /* ret=newval; */
188 "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
189 "beq %0,2f\n" /* if (ret==0) goto 2; */
190 "br 3f\n" /* goto 3; */
191 "2: br 1b\n" /* goto 1; */
192 "3:\n"
193 : "=&r" (ret), "+m" (_q_value)
194 : "r" (expectedValue), "r" (newValue)
195 : "memory");
196 return ret != 0;
197 }
198
fetchAndStoreRelaxed(int newValue)199 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
200 {
201 int old, tmp;
202 asm volatile("1:\n"
203 "ldl_l %0,%2\n" /* old=*ptr; */
204 "mov %3,%1\n" /* tmp=newval; */
205 "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
206 "beq %1,2f\n" /* if (tmp==0) goto 2; */
207 "br 3f\n" /* goto 3; */
208 "2: br 1b\n" /* goto 1; */
209 "3:\n"
210 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
211 : "r" (newValue)
212 : "memory");
213 return old;
214 }
215
fetchAndStoreAcquire(int newValue)216 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
217 {
218 int old, tmp;
219 asm volatile("1:\n"
220 "ldl_l %0,%2\n" /* old=*ptr; */
221 "mov %3,%1\n" /* tmp=newval; */
222 "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
223 "beq %1,2f\n" /* if (tmp==0) goto 2; */
224 "br 3f\n" /* goto 3; */
225 "2: br 1b\n" /* goto 1; */
226 "3:\n"
227 "mb\n"
228 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
229 : "r" (newValue)
230 : "memory");
231 return old;
232 }
233
fetchAndStoreRelease(int newValue)234 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
235 {
236 int old, tmp;
237 asm volatile("mb\n"
238 "1:\n"
239 "ldl_l %0,%2\n" /* old=*ptr; */
240 "mov %3,%1\n" /* tmp=newval; */
241 "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
242 "beq %1,2f\n" /* if (tmp==0) goto 2; */
243 "br 3f\n" /* goto 3; */
244 "2: br 1b\n" /* goto 1; */
245 "3:\n"
246 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
247 : "r" (newValue)
248 : "memory");
249 return old;
250 }
251
fetchAndAddRelaxed(int valueToAdd)252 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
253 {
254 int old, tmp;
255 asm volatile("1:\n"
256 "ldl_l %0,%2\n" /* old=*ptr; */
257 "addl %0,%3,%1\n"/* tmp=old+value; */
258 "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
259 "beq %1,2f\n" /* if (tmp == 0) goto 2; */
260 "br 3f\n" /* goto 3; */
261 "2: br 1b\n" /* goto 1; */
262 "3:\n"
263 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
264 : "r" (valueToAdd)
265 : "memory");
266 return old;
267 }
268
fetchAndAddAcquire(int valueToAdd)269 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
270 {
271 int old, tmp;
272 asm volatile("1:\n"
273 "ldl_l %0,%2\n" /* old=*ptr; */
274 "addl %0,%3,%1\n"/* tmp=old+value; */
275 "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
276 "beq %1,2f\n" /* if (tmp == 0) goto 2; */
277 "br 3f\n" /* goto 3; */
278 "2: br 1b\n" /* goto 1; */
279 "3:\n"
280 "mb\n"
281 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
282 : "r" (valueToAdd)
283 : "memory");
284 return old;
285 }
286
fetchAndAddRelease(int valueToAdd)287 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
288 {
289 int old, tmp;
290 asm volatile("mb\n"
291 "1:\n"
292 "ldl_l %0,%2\n" /* old=*ptr; */
293 "addl %0,%3,%1\n"/* tmp=old+value; */
294 "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
295 "beq %1,2f\n" /* if (tmp == 0) goto 2; */
296 "br 3f\n" /* goto 3; */
297 "2: br 1b\n" /* goto 1; */
298 "3:\n"
299 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
300 : "r" (valueToAdd)
301 : "memory");
302 return old;
303 }
304
305 template <typename T>
testAndSetRelaxed(T * expectedValue,T * newValue)306 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
307 {
308 void *ret;
309 asm volatile("1:\n"
310 "ldq_l %0,%1\n" /* ret=*ptr; */
311 "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
312 "beq %0,3f\n" /* if (tmp==0) goto 3; */
313 "mov %3,%0\n" /* tmp=newval; */
314 "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
315 "beq %0,2f\n" /* if (ret==0) goto 2; */
316 "br 3f\n" /* goto 3; */
317 "2: br 1b\n" /* goto 1; */
318 "3:\n"
319 : "=&r" (ret), "+m" (_q_value)
320 : "r" (expectedValue), "r" (newValue)
321 : "memory");
322 return ret != 0;
323 }
324
325 template <typename T>
testAndSetAcquire(T * expectedValue,T * newValue)326 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
327 {
328 void *ret;
329 asm volatile("1:\n"
330 "ldq_l %0,%1\n" /* ret=*ptr; */
331 "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
332 "beq %0,3f\n" /* if (tmp==0) goto 3; */
333 "mov %3,%0\n" /* tmp=newval; */
334 "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
335 "beq %0,2f\n" /* if (ret==0) goto 2; */
336 "br 3f\n" /* goto 3; */
337 "2: br 1b\n" /* goto 1; */
338 "3:\n"
339 "mb\n"
340 : "=&r" (ret), "+m" (_q_value)
341 : "r" (expectedValue), "r" (newValue)
342 : "memory");
343 return ret != 0;
344 }
345
346 template <typename T>
testAndSetRelease(T * expectedValue,T * newValue)347 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
348 {
349 void *ret;
350 asm volatile("mb\n"
351 "1:\n"
352 "ldq_l %0,%1\n" /* ret=*ptr; */
353 "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
354 "beq %0,3f\n" /* if (tmp==0) goto 3; */
355 "mov %3,%0\n" /* tmp=newval; */
356 "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
357 "beq %0,2f\n" /* if (ret==0) goto 2; */
358 "br 3f\n" /* goto 3; */
359 "2: br 1b\n" /* goto 1; */
360 "3:\n"
361 : "=&r" (ret), "+m" (_q_value)
362 : "r" (expectedValue), "r" (newValue)
363 : "memory");
364 return ret != 0;
365 }
366
367 template <typename T>
fetchAndStoreRelaxed(T * newValue)368 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
369 {
370 T *old, *tmp;
371 asm volatile("1:\n"
372 "ldq_l %0,%2\n" /* old=*ptr; */
373 "mov %3,%1\n" /* tmp=newval; */
374 "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
375 "beq %1,2f\n" /* if (tmp==0) goto 2; */
376 "br 3f\n" /* goto 3; */
377 "2: br 1b\n" /* goto 1; */
378 "3:\n"
379 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
380 : "r" (newValue)
381 : "memory");
382 return old;
383 }
384
385 template <typename T>
fetchAndStoreAcquire(T * newValue)386 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
387 {
388 T *old, *tmp;
389 asm volatile("1:\n"
390 "ldq_l %0,%2\n" /* old=*ptr; */
391 "mov %3,%1\n" /* tmp=newval; */
392 "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
393 "beq %1,2f\n" /* if (tmp==0) goto 2; */
394 "br 3f\n" /* goto 3; */
395 "2: br 1b\n" /* goto 1; */
396 "3:\n"
397 "mb\n"
398 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
399 : "r" (newValue)
400 : "memory");
401 return old;
402 }
403
404 template <typename T>
fetchAndStoreRelease(T * newValue)405 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
406 {
407 T *old, *tmp;
408 asm volatile("mb\n"
409 "1:\n"
410 "ldq_l %0,%2\n" /* old=*ptr; */
411 "mov %3,%1\n" /* tmp=newval; */
412 "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
413 "beq %1,2f\n" /* if (tmp==0) goto 2; */
414 "br 3f\n" /* goto 3; */
415 "2: br 1b\n" /* goto 1; */
416 "3:\n"
417 : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
418 : "r" (newValue)
419 : "memory");
420 return old;
421 }
422
423 template <typename T>
fetchAndAddRelaxed(qptrdiff valueToAdd)424 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
425 {
426 T *old, *tmp;
427 asm volatile("1:\n"
428 "ldq_l %0,%2\n" /* old=*ptr; */
429 "addq %0,%3,%1\n"/* tmp=old+value; */
430 "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
431 "beq %1,2f\n" /* if (tmp == 0) goto 2; */
432 "br 3f\n" /* goto 3; */
433 "2: br 1b\n" /* goto 1; */
434 "3:\n"
435 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
436 : "r" (valueToAdd)
437 : "memory");
438 return reinterpret_cast<T *>(old);
439 }
440
441 template <typename T>
fetchAndAddAcquire(qptrdiff valueToAdd)442 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
443 {
444 T *old, *tmp;
445 asm volatile("1:\n"
446 "ldq_l %0,%2\n" /* old=*ptr; */
447 "addq %0,%3,%1\n"/* tmp=old+value; */
448 "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
449 "beq %1,2f\n" /* if (tmp == 0) goto 2; */
450 "br 3f\n" /* goto 3; */
451 "2: br 1b\n" /* goto 1; */
452 "3:\n"
453 "mb\n"
454 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
455 : "r" (valueToAdd)
456 : "memory");
457 return reinterpret_cast<T *>(old);
458 }
459
460 template <typename T>
fetchAndAddRelease(qptrdiff valueToAdd)461 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
462 {
463 T *old, *tmp;
464 asm volatile("mb\n"
465 "1:\n"
466 "ldq_l %0,%2\n" /* old=*ptr; */
467 "addq %0,%3,%1\n"/* tmp=old+value; */
468 "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
469 "beq %1,2f\n" /* if (tmp == 0) goto 2; */
470 "br 3f\n" /* goto 3; */
471 "2: br 1b\n" /* goto 1; */
472 "3:\n"
473 : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
474 : "r" (valueToAdd)
475 : "memory");
476 return reinterpret_cast<T *>(old);
477 }
478
479 #else // !Q_CC_GNU
480
481 extern "C" {
482 Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
483 Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expected, int newval);
484 Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, int expected, int newval);
485 Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
486 Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr);
487 Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr);
488 Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval);
489 Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval);
490 Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value);
491 Q_CORE_EXPORT int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int value);
492 Q_CORE_EXPORT int q_atomic_fetch_and_add_release_int(volatile int *ptr, int value);
493 } // extern "C"
494
ref()495 inline bool QBasicAtomicInt::ref()
496 {
497 return q_atomic_increment(&_q_value) != 0;
498 }
499
deref()500 inline bool QBasicAtomicInt::deref()
501 {
502 return q_atomic_decrement(&_q_value) != 0;
503 }
504
testAndSetRelaxed(int expectedValue,int newValue)505 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
506 {
507 return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
508 }
509
testAndSetAcquire(int expectedValue,int newValue)510 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
511 {
512 return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
513 }
514
testAndSetRelease(int expectedValue,int newValue)515 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
516 {
517 return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
518 }
519
fetchAndStoreRelaxed(int newValue)520 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
521 {
522 return q_atomic_set_int(&_q_value, newValue);
523 }
524
fetchAndStoreAcquire(int newValue)525 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
526 {
527 return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
528 }
529
fetchAndStoreRelease(int newValue)530 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
531 {
532 return q_atomic_fetch_and_store_release_int(&_q_value, newValue);
533 }
534
fetchAndAddRelaxed(int valueToAdd)535 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
536 {
537 return q_atomic_fetch_and_add_int(&_q_value, valueToAdd);
538 }
539
fetchAndAddAcquire(int valueToAdd)540 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
541 {
542 return q_atomic_fetch_and_add_acquire_int(&_q_value, valueToAdd);
543 }
544
fetchAndAddRelease(int valueToAdd)545 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
546 {
547 return q_atomic_fetch_and_add_release_int(&_q_value, valueToAdd);
548 }
549
550 template <typename T>
testAndSetRelaxed(T * expectedValue,T * newValue)551 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
552 {
553 return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
554 }
555
556 template <typename T>
testAndSetAcquire(T * expectedValue,T * newValue)557 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
558 {
559 return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
560 }
561
562 template <typename T>
testAndSetRelease(T * expectedValue,T * newValue)563 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
564 {
565 return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
566 }
567
568 template <typename T>
fetchAndStoreRelaxed(T * newValue)569 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
570 {
571 return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
572 }
573
574 template <typename T>
fetchAndStoreAcquire(T * newValue)575 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
576 {
577 return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
578 }
579
580 template <typename T>
fetchAndStoreRelease(T * newValue)581 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
582 {
583 return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue));
584 }
585
586 template <typename T>
fetchAndAddRelaxed(qptrdiff valueToAdd)587 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
588 {
589 return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, newValue));
590 }
591 template <typename T>
fetchAndAddAcquire(qptrdiff valueToAdd)592 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
593 {
594 return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, newValue));
595 }
596
597 template <typename T>
fetchAndAddRelease(qptrdiff valueToAdd)598 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
599 {
600 return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, newValue));
601 }
602
603 #endif // Q_CC_GNU
604
testAndSetOrdered(int expectedValue,int newValue)605 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
606 {
607 return testAndSetAcquire(expectedValue, newValue);
608 }
609
fetchAndStoreOrdered(int newValue)610 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
611 {
612 return fetchAndStoreAcquire(newValue);
613 }
614
fetchAndAddOrdered(int valueToAdd)615 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
616 {
617 return fetchAndAddAcquire(valueToAdd);
618 }
619
620 template <typename T>
testAndSetOrdered(T * expectedValue,T * newValue)621 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
622 {
623 return testAndSetAcquire(expectedValue, newValue);
624 }
625
626 template <typename T>
fetchAndStoreOrdered(T * newValue)627 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
628 {
629 return fetchAndStoreAcquire(newValue);
630 }
631
632 template <typename T>
fetchAndAddOrdered(qptrdiff valueToAdd)633 Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
634 {
635 return fetchAndAddAcquire(valueToAdd);
636 }
637
638 QT_END_NAMESPACE
639
640 QT_END_HEADER
641
642 #endif // QATOMIC_ALPHA_H
643