Qt 4.8
qatomic_sh.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_SH_H
43 #define QATOMIC_SH_H
44 
46 
48 
49 #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
50 
52 { return false; }
54 { return false; }
55 
56 #define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
57 
59 { return false; }
61 { return false; }
62 
63 #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
64 
66 { return false; }
68 { return false; }
69 
70 #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
71 
73 { return false; }
75 { return false; }
76 
77 #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
78 
79 template <typename T>
81 { return false; }
82 template <typename T>
84 { return false; }
85 
86 #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE
87 
88 template <typename T>
90 { return false; }
91 template <typename T>
93 { return false; }
94 
95 #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE
96 
97 template <typename T>
99 { return false; }
100 template <typename T>
102 { return false; }
103 
104 extern Q_CORE_EXPORT volatile char qt_atomic_lock;
105 Q_CORE_EXPORT void qt_atomic_yield(int *count);
106 
107 inline int qt_atomic_tasb(volatile char *ptr)
108 {
109  register int ret;
110  asm volatile("tas.b @%2\n"
111  "movt %0"
112  : "=&r"(ret), "=m"(*ptr)
113  : "r"(ptr)
114  : "cc", "memory");
115  return ret;
116 }
117 
118 // Reference counting
119 
120 inline bool QBasicAtomicInt::ref()
121 {
122  int count = 0;
123  while (qt_atomic_tasb(&qt_atomic_lock) == 0)
124  qt_atomic_yield(&count);
125  int originalValue = _q_value++;
126  qt_atomic_lock = 0;
127  return originalValue != -1;
128 }
129 
130 inline bool QBasicAtomicInt::deref()
131 {
132  int count = 0;
133  while (qt_atomic_tasb(&qt_atomic_lock) == 0)
134  qt_atomic_yield(&count);
135  int originalValue = _q_value--;
136  qt_atomic_lock = 0;
137  return originalValue != 1;
138 }
139 
140 // Test and set for integers
141 
142 inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
143 {
144  bool returnValue = false;
145  int count = 0;
146  while (qt_atomic_tasb(&qt_atomic_lock) == 0)
147  qt_atomic_yield(&count);
148  if (_q_value == expectedValue) {
149  _q_value = newValue;
150  returnValue = true;
151  }
152  qt_atomic_lock = 0;
153  return returnValue;
154 }
155 
156 inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
157 {
158  return testAndSetOrdered(expectedValue, newValue);
159 }
160 
161 inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
162 {
163  return testAndSetOrdered(expectedValue, newValue);
164 }
165 
166 inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
167 {
168  return testAndSetOrdered(expectedValue, newValue);
169 }
170 
171 // Fetch and store for integers
172 
173 inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
174 {
175  int count = 0;
176  while (qt_atomic_tasb(&qt_atomic_lock) == 0)
177  qt_atomic_yield(&count);
178  int originalValue = _q_value;
179  _q_value = newValue;
180  qt_atomic_lock = 0;
181  return originalValue;
182 }
183 
184 inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
185 {
186  return fetchAndStoreOrdered(newValue);
187 }
188 
189 inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
190 {
191  return fetchAndStoreOrdered(newValue);
192 }
193 
194 inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
195 {
196  return fetchAndStoreOrdered(newValue);
197 }
198 
199 // Fetch and add for integers
200 
201 inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
202 {
203  int count = 0;
204  while (qt_atomic_tasb(&qt_atomic_lock) == 0)
205  qt_atomic_yield(&count);
206  int originalValue = _q_value;
207  _q_value += valueToAdd;
208  qt_atomic_lock = 0;
209  return originalValue;
210 }
211 
212 inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
213 {
214  return fetchAndAddOrdered(valueToAdd);
215 }
216 
217 inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
218 {
219  return fetchAndAddOrdered(valueToAdd);
220 }
221 
222 inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
223 {
224  return fetchAndAddOrdered(valueToAdd);
225 }
226 
227 // Test and set for pointers
228 
229 template <typename T>
230 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
231 {
232  bool returnValue = false;
233  int count = 0;
234  while (qt_atomic_tasb(&qt_atomic_lock) == 0)
235  qt_atomic_yield(&count);
236  if (_q_value == expectedValue) {
237  _q_value = newValue;
238  returnValue = true;
239  }
240  qt_atomic_lock = 0;
241  return returnValue;
242 }
243 
244 template <typename T>
245 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
246 {
247  return testAndSetOrdered(expectedValue, newValue);
248 }
249 
250 template <typename T>
251 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
252 {
253  return testAndSetOrdered(expectedValue, newValue);
254 }
255 
256 template <typename T>
257 Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
258 {
259  return testAndSetOrdered(expectedValue, newValue);
260 }
261 
262 // Fetch and store for pointers
263 
264 template <typename T>
266 {
267  int count = 0;
268  while (qt_atomic_tasb(&qt_atomic_lock) == 0)
269  qt_atomic_yield(&count);
270  T *originalValue = _q_value;
271  _q_value = newValue;
272  qt_atomic_lock = 0;
273  return originalValue;
274 }
275 
276 template <typename T>
278 {
279  return fetchAndStoreOrdered(newValue);
280 }
281 
282 template <typename T>
284 {
285  return fetchAndStoreOrdered(newValue);
286 }
287 
288 template <typename T>
290 {
291  return fetchAndStoreOrdered(newValue);
292 }
293 
294 // Fetch and add for pointers
295 
296 template <typename T>
298 {
299  int count = 0;
300  while (qt_atomic_tasb(&qt_atomic_lock) == 0)
301  qt_atomic_yield(&count);
302  T *originalValue = (_q_value);
303  _q_value += valueToAdd;
304  qt_atomic_lock = 0;
305  return originalValue;
306 }
307 
308 template <typename T>
310 {
311  return fetchAndAddOrdered(valueToAdd);
312 }
313 
314 template <typename T>
316 {
317  return fetchAndAddOrdered(valueToAdd);
318 }
319 
320 template <typename T>
322 {
323  return fetchAndAddOrdered(valueToAdd);
324 }
325 
327 
329 
330 #endif // QATOMIC_SH_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
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)
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)
Q_CORE_EXPORT void qt_atomic_yield(int *count)
Definition: qatomic_arm.cpp:56
#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
static bool isTestAndSetWaitFree()
Definition: qatomic_alpha.h:60
int qt_atomic_tasb(volatile char *ptr)
Definition: qatomic_sh.h:107
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 volatile char qt_atomic_lock
Definition: qatomic_sh.cpp:54
int fetchAndAddRelaxed(int valueToAdd)
int fetchAndStoreOrdered(int newValue)
bool testAndSetRelaxed(T *expectedValue, T *newValue)
bool testAndSetRelease(T *expectedValue, T *newValue)
#define QT_END_HEADER
Definition: qglobal.h:137
T * fetchAndStoreRelaxed(T *newValue)
static bool isFetchAndStoreNative()
Definition: qatomic_alpha.h:89
bool testAndSetAcquire(T *expectedValue, T *newValue)