Qt 4.8
qatomic_mips.h
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #ifndef QATOMIC_MIPS_H
43 #define QATOMIC_MIPS_H
44 
46 
48 
49 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
50 
52 { return true; }
54 { return false; }
55 
56 #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
57 
59 { return true; }
61 { return false; }
62 
63 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
64 
66 { return true; }
68 { return false; }
69 
70 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
71 
73 { return true; }
75 { return false; }
76 
77 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
78 
79 template <typename T>
81 { return true; }
82 template <typename T>
84 { return false; }
85 
86 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
87 
88 template <typename T>
90 { return true; }
91 template <typename T>
93 { return false; }
94 
95 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
96 
97 template <typename T>
99 { return true; }
100 template <typename T>
102 { return false; }
103 
104 #if defined(Q_CC_GNU) && !defined(Q_OS_IRIX)
105 
106 #if _MIPS_SIM == _ABIO32
107 #define SET_MIPS2 ".set mips2\n\t"
108 #else
109 #define SET_MIPS2
110 #endif
111 
112 inline bool QBasicAtomicInt::ref()
113 {
114  register int originalValue;
115  register int newValue;
116  asm volatile(".set push\n"
117  SET_MIPS2
118  "0:\n"
119  "ll %[originalValue], %[_q_value]\n"
120  "addiu %[newValue], %[originalValue], %[one]\n"
121  "sc %[newValue], %[_q_value]\n"
122  "beqz %[newValue], 0b\n"
123  "nop\n"
124  ".set pop\n"
125  : [originalValue] "=&r" (originalValue),
126  [_q_value] "+m" (_q_value),
127  [newValue] "=&r" (newValue)
128  : [one] "i" (1)
129  : "cc", "memory");
130  return originalValue != -1;
131 }
132 
133 inline bool QBasicAtomicInt::deref()
134 {
135  register int originalValue;
136  register int newValue;
137  asm volatile(".set push\n"
138  SET_MIPS2
139  "0:\n"
140  "ll %[originalValue], %[_q_value]\n"
141  "addiu %[newValue], %[originalValue], %[minusOne]\n"
142  "sc %[newValue], %[_q_value]\n"
143  "beqz %[newValue], 0b\n"
144  "nop\n"
145  ".set pop\n"
146  : [originalValue] "=&r" (originalValue),
147  [_q_value] "+m" (_q_value),
148  [newValue] "=&r" (newValue)
149  : [minusOne] "i" (-1)
150  : "cc", "memory");
151  return originalValue != 1;
152 }
153 
154 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
155 {
156  register int result;
157  register int tempValue;
158  asm volatile(".set push\n"
159  SET_MIPS2
160  "0:\n"
161  "ll %[result], %[_q_value]\n"
162  "xor %[result], %[result], %[expectedValue]\n"
163  "bnez %[result], 0f\n"
164  "nop\n"
165  "move %[tempValue], %[newValue]\n"
166  "sc %[tempValue], %[_q_value]\n"
167  "beqz %[tempValue], 0b\n"
168  "nop\n"
169  "0:\n"
170  ".set pop\n"
171  : [result] "=&r" (result),
172  [tempValue] "=&r" (tempValue),
173  [_q_value] "+m" (_q_value)
174  : [expectedValue] "r" (expectedValue),
175  [newValue] "r" (newValue)
176  : "cc", "memory");
177  return result == 0;
178 }
179 
180 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
181 {
182  register int result;
183  register int tempValue;
184  asm volatile(".set push\n"
185  SET_MIPS2
186  "0:\n"
187  "ll %[result], %[_q_value]\n"
188  "xor %[result], %[result], %[expectedValue]\n"
189  "bnez %[result], 0f\n"
190  "nop\n"
191  "move %[tempValue], %[newValue]\n"
192  "sc %[tempValue], %[_q_value]\n"
193  "beqz %[tempValue], 0b\n"
194  "nop\n"
195  "sync\n"
196  "0:\n"
197  ".set pop\n"
198  : [result] "=&r" (result),
199  [tempValue] "=&r" (tempValue),
200  [_q_value] "+m" (_q_value)
201  : [expectedValue] "r" (expectedValue),
202  [newValue] "r" (newValue)
203  : "cc", "memory");
204  return result == 0;
205 }
206 
207 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
208 {
209  register int result;
210  register int tempValue;
211  asm volatile(".set push\n"
212  SET_MIPS2
213  "sync\n"
214  "0:\n"
215  "ll %[result], %[_q_value]\n"
216  "xor %[result], %[result], %[expectedValue]\n"
217  "bnez %[result], 0f\n"
218  "nop\n"
219  "move %[tempValue], %[newValue]\n"
220  "sc %[tempValue], %[_q_value]\n"
221  "beqz %[tempValue], 0b\n"
222  "nop\n"
223  "0:\n"
224  ".set pop\n"
225  : [result] "=&r" (result),
226  [tempValue] "=&r" (tempValue),
227  [_q_value] "+m" (_q_value)
228  : [expectedValue] "r" (expectedValue),
229  [newValue] "r" (newValue)
230  : "cc", "memory");
231  return result == 0;
232 }
233 
234 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
235 {
236  return testAndSetAcquire(expectedValue, newValue);
237 }
238 
239 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
240 {
241  register int originalValue;
242  register int tempValue;
243  asm volatile(".set push\n"
244  SET_MIPS2
245  "0:\n"
246  "ll %[originalValue], %[_q_value]\n"
247  "move %[tempValue], %[newValue]\n"
248  "sc %[tempValue], %[_q_value]\n"
249  "beqz %[tempValue], 0b\n"
250  "nop\n"
251  ".set pop\n"
252  : [originalValue] "=&r" (originalValue),
253  [tempValue] "=&r" (tempValue),
254  [_q_value] "+m" (_q_value)
255  : [newValue] "r" (newValue)
256  : "cc", "memory");
257  return originalValue;
258 }
259 
260 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
261 {
262  register int originalValue;
263  register int tempValue;
264  asm volatile(".set push\n"
265  SET_MIPS2
266  "0:\n"
267  "ll %[originalValue], %[_q_value]\n"
268  "move %[tempValue], %[newValue]\n"
269  "sc %[tempValue], %[_q_value]\n"
270  "beqz %[tempValue], 0b\n"
271  "nop\n"
272  "sync\n"
273  ".set pop\n"
274  : [originalValue] "=&r" (originalValue),
275  [tempValue] "=&r" (tempValue),
276  [_q_value] "+m" (_q_value)
277  : [newValue] "r" (newValue)
278  : "cc", "memory");
279  return originalValue;
280 }
281 
282 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
283 {
284  register int originalValue;
285  register int tempValue;
286  asm volatile(".set push\n"
287  SET_MIPS2
288  "sync\n"
289  "0:\n"
290  "ll %[originalValue], %[_q_value]\n"
291  "move %[tempValue], %[newValue]\n"
292  "sc %[tempValue], %[_q_value]\n"
293  "beqz %[tempValue], 0b\n"
294  "nop\n"
295  ".set pop\n"
296  : [originalValue] "=&r" (originalValue),
297  [tempValue] "=&r" (tempValue),
298  [_q_value] "+m" (_q_value)
299  : [newValue] "r" (newValue)
300  : "cc", "memory");
301  return originalValue;
302 }
303 
304 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
305 {
306  return fetchAndStoreAcquire(newValue);
307 }
308 
309 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
310 {
311  register int originalValue;
312  register int newValue;
313  asm volatile(".set push\n"
314  SET_MIPS2
315  "0:\n"
316  "ll %[originalValue], %[_q_value]\n"
317  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
318  "sc %[newValue], %[_q_value]\n"
319  "beqz %[newValue], 0b\n"
320  "nop\n"
321  ".set pop\n"
322  : [originalValue] "=&r" (originalValue),
323  [_q_value] "+m" (_q_value),
324  [newValue] "=&r" (newValue)
325  : [valueToAdd] "r" (valueToAdd)
326  : "cc", "memory");
327  return originalValue;
328 }
329 
330 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
331 {
332  register int originalValue;
333  register int newValue;
334  asm volatile(".set push\n"
335  SET_MIPS2
336  "0:\n"
337  "ll %[originalValue], %[_q_value]\n"
338  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
339  "sc %[newValue], %[_q_value]\n"
340  "beqz %[newValue], 0b\n"
341  "nop\n"
342  "sync\n"
343  ".set pop\n"
344  : [originalValue] "=&r" (originalValue),
345  [_q_value] "+m" (_q_value),
346  [newValue] "=&r" (newValue)
347  : [valueToAdd] "r" (valueToAdd)
348  : "cc", "memory");
349  return originalValue;
350 }
351 
352 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
353 {
354  register int originalValue;
355  register int newValue;
356  asm volatile(".set push\n"
357  SET_MIPS2
358  "sync\n"
359  "0:\n"
360  "ll %[originalValue], %[_q_value]\n"
361  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
362  "sc %[newValue], %[_q_value]\n"
363  "beqz %[newValue], 0b\n"
364  "nop\n"
365  ".set pop\n"
366  : [originalValue] "=&r" (originalValue),
367  [_q_value] "+m" (_q_value),
368  [newValue] "=&r" (newValue)
369  : [valueToAdd] "r" (valueToAdd)
370  : "cc", "memory");
371  return originalValue;
372 }
373 
374 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
375 {
376  return fetchAndAddAcquire(valueToAdd);
377 }
378 
379 #if defined(__LP64__)
380 # define LLP "lld"
381 # define SCP "scd"
382 #else
383 # define LLP "ll"
384 # define SCP "sc"
385 #endif
386 
387 template <typename T>
388 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
389 {
390  register T *result;
391  register T *tempValue;
392  asm volatile(".set push\n"
393  SET_MIPS2
394  "0:\n"
395  LLP" %[result], %[_q_value]\n"
396  "xor %[result], %[result], %[expectedValue]\n"
397  "bnez %[result], 0f\n"
398  "nop\n"
399  "move %[tempValue], %[newValue]\n"
400  SCP" %[tempValue], %[_q_value]\n"
401  "beqz %[tempValue], 0b\n"
402  "nop\n"
403  "0:\n"
404  ".set pop\n"
405  : [result] "=&r" (result),
406  [tempValue] "=&r" (tempValue),
407  [_q_value] "+m" (_q_value)
408  : [expectedValue] "r" (expectedValue),
409  [newValue] "r" (newValue)
410  : "cc", "memory");
411  return result == 0;
412 }
413 
414 template <typename T>
415 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
416 {
417  register T *result;
418  register T *tempValue;
419  asm volatile(".set push\n"
420  SET_MIPS2
421  "0:\n"
422  LLP" %[result], %[_q_value]\n"
423  "xor %[result], %[result], %[expectedValue]\n"
424  "bnez %[result], 0f\n"
425  "nop\n"
426  "move %[tempValue], %[newValue]\n"
427  SCP" %[tempValue], %[_q_value]\n"
428  "beqz %[tempValue], 0b\n"
429  "nop\n"
430  "sync\n"
431  "0:\n"
432  ".set pop\n"
433  : [result] "=&r" (result),
434  [tempValue] "=&r" (tempValue),
435  [_q_value] "+m" (_q_value)
436  : [expectedValue] "r" (expectedValue),
437  [newValue] "r" (newValue)
438  : "cc", "memory");
439  return result == 0;
440 }
441 
442 template <typename T>
443 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
444 {
445  register T *result;
446  register T *tempValue;
447  asm volatile(".set push\n"
448  SET_MIPS2
449  "sync\n"
450  "0:\n"
451  LLP" %[result], %[_q_value]\n"
452  "xor %[result], %[result], %[expectedValue]\n"
453  "bnez %[result], 0f\n"
454  "nop\n"
455  "move %[tempValue], %[newValue]\n"
456  SCP" %[tempValue], %[_q_value]\n"
457  "beqz %[tempValue], 0b\n"
458  "nop\n"
459  "0:\n"
460  ".set pop\n"
461  : [result] "=&r" (result),
462  [tempValue] "=&r" (tempValue),
463  [_q_value] "+m" (_q_value)
464  : [expectedValue] "r" (expectedValue),
465  [newValue] "r" (newValue)
466  : "cc", "memory");
467  return result == 0;
468 }
469 
470 template <typename T>
471 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
472 {
473  return testAndSetAcquire(expectedValue, newValue);
474 }
475 
476 template <typename T>
478 {
479  register T *originalValue;
480  register T *tempValue;
481  asm volatile(".set push\n"
482  SET_MIPS2
483  "0:\n"
484  LLP" %[originalValue], %[_q_value]\n"
485  "move %[tempValue], %[newValue]\n"
486  SCP" %[tempValue], %[_q_value]\n"
487  "beqz %[tempValue], 0b\n"
488  "nop\n"
489  ".set pop\n"
490  : [originalValue] "=&r" (originalValue),
491  [tempValue] "=&r" (tempValue),
492  [_q_value] "+m" (_q_value)
493  : [newValue] "r" (newValue)
494  : "cc", "memory");
495  return originalValue;
496 }
497 
498 template <typename T>
500 {
501  register T *originalValue;
502  register T *tempValue;
503  asm volatile(".set push\n"
504  SET_MIPS2
505  "0:\n"
506  LLP" %[originalValue], %[_q_value]\n"
507  "move %[tempValue], %[newValue]\n"
508  SCP" %[tempValue], %[_q_value]\n"
509  "beqz %[tempValue], 0b\n"
510  "nop\n"
511  "sync\n"
512  ".set pop\n"
513  : [originalValue] "=&r" (originalValue),
514  [tempValue] "=&r" (tempValue),
515  [_q_value] "+m" (_q_value)
516  : [newValue] "r" (newValue)
517  : "cc", "memory");
518  return originalValue;
519 }
520 
521 template <typename T>
523 {
524  register T *originalValue;
525  register T *tempValue;
526  asm volatile(".set push\n"
527  SET_MIPS2
528  "sync\n"
529  "0:\n"
530  LLP" %[originalValue], %[_q_value]\n"
531  "move %[tempValue], %[newValue]\n"
532  SCP" %[tempValue], %[_q_value]\n"
533  "beqz %[tempValue], 0b\n"
534  "nop\n"
535  ".set pop\n"
536  : [originalValue] "=&r" (originalValue),
537  [tempValue] "=&r" (tempValue),
538  [_q_value] "+m" (_q_value)
539  : [newValue] "r" (newValue)
540  : "cc", "memory");
541  return originalValue;
542 }
543 
544 template <typename T>
546 {
547  return fetchAndStoreAcquire(newValue);
548 }
549 
550 template <typename T>
552 {
553  register T *originalValue;
554  register T *newValue;
555  asm volatile(".set push\n"
556  SET_MIPS2
557  "0:\n"
558  LLP" %[originalValue], %[_q_value]\n"
559  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
560  SCP" %[newValue], %[_q_value]\n"
561  "beqz %[newValue], 0b\n"
562  "nop\n"
563  ".set pop\n"
564  : [originalValue] "=&r" (originalValue),
565  [_q_value] "+m" (_q_value),
566  [newValue] "=&r" (newValue)
567  : [valueToAdd] "r" (valueToAdd * sizeof(T))
568  : "cc", "memory");
569  return originalValue;
570 }
571 
572 template <typename T>
574 {
575  register T *originalValue;
576  register T *newValue;
577  asm volatile(".set push\n"
578  SET_MIPS2
579  "0:\n"
580  LLP" %[originalValue], %[_q_value]\n"
581  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
582  SCP" %[newValue], %[_q_value]\n"
583  "beqz %[newValue], 0b\n"
584  "nop\n"
585  "sync\n"
586  ".set pop\n"
587  : [originalValue] "=&r" (originalValue),
588  [_q_value] "+m" (_q_value),
589  [newValue] "=&r" (newValue)
590  : [valueToAdd] "r" (valueToAdd * sizeof(T))
591  : "cc", "memory");
592  return originalValue;
593 }
594 
595 template <typename T>
597 {
598  register T *originalValue;
599  register T *newValue;
600  asm volatile(".set push\n"
601  SET_MIPS2
602  "sync\n"
603  "0:\n"
604  LLP" %[originalValue], %[_q_value]\n"
605  "addu %[newValue], %[originalValue], %[valueToAdd]\n"
606  SCP" %[newValue], %[_q_value]\n"
607  "beqz %[newValue], 0b\n"
608  "nop\n"
609  ".set pop\n"
610  : [originalValue] "=&r" (originalValue),
611  [_q_value] "+m" (_q_value),
612  [newValue] "=&r" (newValue)
613  : [valueToAdd] "r" (valueToAdd * sizeof(T))
614  : "cc", "memory");
615  return originalValue;
616 }
617 
618 template <typename T>
620 {
621  return fetchAndAddAcquire(valueToAdd);
622 }
623 
624 #else // !Q_CC_GNU
625 
626 extern "C" {
627  Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
628  Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expected, int newval);
629  Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, int expected, int newval);
630  Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
631  Q_CORE_EXPORT int q_atomic_test_and_set_acquire_ptr(volatile void *ptr, void *expected, void *newval);
632  Q_CORE_EXPORT int q_atomic_test_and_set_release_ptr(volatile void *ptr, void *expected, void *newval);
633 } // extern "C"
634 
635 inline bool QBasicAtomicInt::ref()
636 {
637  register int expected;
638  for (;;) {
639  expected = _q_value;
640  if (q_atomic_test_and_set_int(&_q_value, expected, expected + 1))
641  break;
642  }
643  return expected != -1;
644 }
645 
646 inline bool QBasicAtomicInt::deref()
647 {
648  register int expected;
649  for (;;) {
650  expected = _q_value;
651  if (q_atomic_test_and_set_int(&_q_value, expected, expected - 1))
652  break;
653  }
654  return expected != 1;
655 }
656 
657 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
658 {
659  return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0;
660 }
661 
662 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
663 {
664  return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
665 }
666 
667 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
668 {
669  return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0;
670 }
671 
672 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
673 {
674  return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0;
675 }
676 
677 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
678 {
679  int returnValue;
680  for (;;) {
681  returnValue = _q_value;
682  if (testAndSetRelaxed(returnValue, newValue))
683  break;
684  }
685  return returnValue;
686 }
687 
688 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
689 {
690  int returnValue;
691  for (;;) {
692  returnValue = _q_value;
693  if (testAndSetAcquire(returnValue, newValue))
694  break;
695  }
696  return returnValue;
697 }
698 
699 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
700 {
701  int returnValue;
702  for (;;) {
703  returnValue = _q_value;
704  if (testAndSetRelease(returnValue, newValue))
705  break;
706  }
707  return returnValue;
708 }
709 
710 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
711 {
712  int returnValue;
713  for (;;) {
714  returnValue = _q_value;
715  if (testAndSetOrdered(returnValue, newValue))
716  break;
717  }
718  return returnValue;
719 }
720 
721 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
722 {
723  int returnValue;
724  for (;;) {
725  returnValue = _q_value;
726  if (testAndSetRelaxed(returnValue, returnValue + valueToAdd))
727  break;
728  }
729  return returnValue;
730 }
731 
732 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
733 {
734  int returnValue;
735  for (;;) {
736  returnValue = _q_value;
737  if (testAndSetAcquire(returnValue, returnValue + valueToAdd))
738  break;
739  }
740  return returnValue;
741 }
742 
743 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
744 {
745  int returnValue;
746  for (;;) {
747  returnValue = _q_value;
748  if (testAndSetRelease(returnValue, returnValue + valueToAdd))
749  break;
750  }
751  return returnValue;
752 }
753 
754 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
755 {
756  int returnValue;
757  for (;;) {
758  returnValue = _q_value;
759  if (testAndSetOrdered(returnValue, returnValue + valueToAdd))
760  break;
761  }
762  return returnValue;
763 }
764 
765 template <typename T>
766 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
767 {
768  return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0;
769 }
770 
771 template <typename T>
772 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
773 {
774  return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
775 }
776 
777 template <typename T>
778 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
779 {
780  return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0;
781 }
782 
783 template <typename T>
784 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
785 {
786  return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0;
787 }
788 
789 template <typename T>
791 {
792  T *returnValue;
793  for (;;) {
794  returnValue = (_q_value);
795  if (testAndSetRelaxed(returnValue, newValue))
796  break;
797  }
798  return returnValue;
799 }
800 
801 template <typename T>
803 {
804  T *returnValue;
805  for (;;) {
806  returnValue = (_q_value);
807  if (testAndSetAcquire(returnValue, newValue))
808  break;
809  }
810  return returnValue;
811 }
812 
813 template <typename T>
815 {
816  T *returnValue;
817  for (;;) {
818  returnValue = (_q_value);
819  if (testAndSetRelease(returnValue, newValue))
820  break;
821  }
822  return returnValue;
823 }
824 
825 template <typename T>
827 {
828  T *returnValue;
829  for (;;) {
830  returnValue = (_q_value);
831  if (testAndSetOrdered(returnValue, newValue))
832  break;
833  }
834  return returnValue;
835 }
836 
837 template <typename T>
839 {
840  T *returnValue;
841  for (;;) {
842  returnValue = (_q_value);
843  if (testAndSetRelaxed(returnValue, returnValue + valueToAdd))
844  break;
845  }
846  return returnValue;
847 }
848 
849 template <typename T>
852 {
853  T *returnValue;
854  for (;;) {
855  returnValue = (_q_value);
856  if (testAndSetAcquire(returnValue, returnValue + valueToAdd))
857  break;
858  }
859  return returnValue;
860 }
861 
862 template <typename T>
864 {
865  T *returnValue;
866  for (;;) {
867  returnValue = (_q_value);
868  if (testAndSetRelease(returnValue, returnValue + valueToAdd))
869  break;
870  }
871  return returnValue;
872 }
873 
874 template <typename T>
876 {
877  T *returnValue;
878  for (;;) {
879  returnValue = (_q_value);
880  if (testAndSetOrdered(returnValue, returnValue + valueToAdd))
881  break;
882  }
883  return returnValue;
884 }
885 
886 #endif // Q_CC_GNU
887 
889 
891 
892 #endif // QATOMIC_MIPS_H
static bool isFetchAndStoreNative()
Definition: qatomic_alpha.h:65
static bool isTestAndSetNative()
Definition: qatomic_alpha.h:58
int fetchAndStoreRelease(int newValue)
static bool isReferenceCountingNative()
Definition: qatomic_alpha.h:51
T * fetchAndAddRelaxed(qptrdiff valueToAdd)
volatile int _q_value
Definition: qbasicatomic.h:64
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static bool isFetchAndAddNative()
Definition: qatomic_alpha.h:98
#define QT_BEGIN_HEADER
Definition: qglobal.h:136
static bool isTestAndSetNative()
Definition: qatomic_alpha.h:80
static bool isFetchAndAddNative()
Definition: qatomic_alpha.h:72
Q_CORE_EXPORT int q_atomic_test_and_set_acquire_ptr(volatile void *ptr, void *expected, void *newval)
T * fetchAndStoreRelease(T *newValue)
static bool isTestAndSetWaitFree()
Definition: qatomic_alpha.h:83
T * fetchAndAddRelease(qptrdiff valueToAdd)
bool testAndSetOrdered(T *expectedValue, T *newValue)
int fetchAndAddAcquire(int valueToAdd)
T * fetchAndAddAcquire(qptrdiff valueToAdd)
int fetchAndStoreRelaxed(int newValue)
T * fetchAndAddOrdered(qptrdiff valueToAdd)
bool testAndSetAcquire(int expectedValue, int newValue)
Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval)
bool testAndSetRelaxed(int expectedValue, int newValue)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
int fetchAndStoreAcquire(int newValue)
QIntegerForSizeof< void * >::Signed qptrdiff
Definition: qglobal.h:987
T * fetchAndStoreOrdered(T *newValue)
#define Q_INLINE_TEMPLATE
Definition: qglobal.h:1713
int fetchAndAddRelease(int valueToAdd)
const T * ptr(const T &t)
bool testAndSetOrdered(int expectedValue, int newValue)
T * fetchAndStoreAcquire(T *newValue)
static bool isFetchAndStoreWaitFree()
Definition: qatomic_alpha.h:67
Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, int expected, int newval)
static bool isTestAndSetWaitFree()
Definition: qatomic_alpha.h:60
static bool isReferenceCountingWaitFree()
Definition: qatomic_alpha.h:53
int fetchAndAddOrdered(int valueToAdd)
static bool isFetchAndStoreWaitFree()
Definition: qatomic_alpha.h:92
static bool isFetchAndAddWaitFree()
Definition: qatomic_alpha.h:74
static bool isFetchAndAddWaitFree()
bool testAndSetRelease(int expectedValue, int newValue)
#define Q_CORE_EXPORT
Definition: qglobal.h:1449
Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expected, int newval)
int fetchAndAddRelaxed(int valueToAdd)
int fetchAndStoreOrdered(int newValue)
bool testAndSetRelaxed(T *expectedValue, T *newValue)
Q_CORE_EXPORT int q_atomic_test_and_set_release_ptr(volatile void *ptr, void *expected, void *newval)
bool testAndSetRelease(T *expectedValue, T *newValue)
#define QT_END_HEADER
Definition: qglobal.h:137
T * fetchAndStoreRelaxed(T *newValue)
Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval)
static bool isFetchAndStoreNative()
Definition: qatomic_alpha.h:89
bool testAndSetAcquire(T *expectedValue, T *newValue)