1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the core module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
32
#if defined(QT_MOC) || defined(QT_BUILD_QMAKE) || defined(QT_RCC) || defined(QT_UIC)
33
// this allows us to use -I... magic to select a specific arch (e.g. generic)
34
# include <arch/qatomic.h>
36
# include <QtCore/arch/qatomic.h>
39
#ifndef Q_SPECIALIZED_QATOMIC
42
We assume that the following 6 functions have been declared by the
43
platform specific qatomic.h:
45
int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval);
46
int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
47
int q_atomic_increment(volatile int *ptr);
48
int q_atomic_decrement(volatile int *ptr);
49
int q_atomic_set_int(volatile int *ptr, int newval);
50
void *q_atomic_set_ptr(volatile void *ptr, void *newval);
52
If you cannot implement these functions efficiently on your
53
platform without great difficulty, consider defining
54
Q_SPECIALIZED_QATOMIC. By doing this, you need to implement:
57
template <typename T> struct QBasicAtomicPointer<T>;
58
int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval);
59
void *q_atomic_set_ptr(volatile void *ptr, void *newval);
69
{ return q_atomic_increment(&atomic) != 0; }
72
{ return q_atomic_decrement(&atomic) != 0; }
74
inline bool operator==(int x) const
75
{ return atomic == x; }
77
inline bool operator!=(int x) const
78
{ return atomic != x; }
80
inline bool operator!() const
81
{ return atomic == 0; }
83
inline operator int() const
86
inline QBasicAtomic &operator=(int x)
88
(void) q_atomic_set_int(&atomic, x);
92
inline bool testAndSet(int expected, int newval)
93
{ return q_atomic_test_and_set_int(&atomic, expected, newval) != 0; }
95
inline int exchange(int newval)
96
{ return q_atomic_set_int(&atomic, newval); }
100
struct QBasicAtomicPointer
107
inline bool operator==(T *t) const
108
{ return pointer == t; }
110
inline bool operator!=(T *t) const
111
{ return !operator==(t); }
113
inline bool operator!() const
114
{ return operator==(0); }
116
inline operator T *() const
117
{ return const_cast<T *>(pointer); }
119
inline T *operator->() const
120
{ return const_cast<T *>(pointer); }
122
inline QBasicAtomicPointer<T> &operator=(T *t)
124
(void) q_atomic_set_ptr(&pointer, t);
128
inline bool testAndSet(T *expected, T *newval)
129
{ return q_atomic_test_and_set_ptr(&pointer, expected, newval); }
131
inline T *exchange(T * newval)
132
{ return static_cast<T *>(q_atomic_set_ptr(&pointer, newval)); }
135
#define Q_ATOMIC_INIT(a) { (a) }
137
#endif // Q_SPECIALIZED_QATOMIC
139
template <typename T>
140
inline T qAtomicSetPtr(volatile T *ptr, T newval)
141
{ return static_cast<T>(q_atomic_set_ptr(ptr, newval)); }
143
// High-level atomic integer operations
144
class QAtomic : public QBasicAtomic
147
inline QAtomic(int x = 0)
149
inline QAtomic(const QAtomic ©)
152
inline QAtomic &operator=(int x)
154
(void) QBasicAtomic::operator=(x);
158
inline QAtomic &operator=(const QAtomic ©)
160
(void) QBasicAtomic::operator=(copy);
165
// High-level atomic pointer operations
166
template <typename T>
167
class QAtomicPointer : public QBasicAtomicPointer<T>
170
inline QAtomicPointer(T *t = 0)
172
inline QAtomicPointer(const QAtomicPointer<T> ©)
175
inline QAtomicPointer<T> &operator=(T *t)
177
(void) QBasicAtomicPointer<T>::operator=(t);
181
inline QAtomicPointer<T> &operator=(const QAtomicPointer<T> ©)
183
(void) QBasicAtomicPointer<T>::operator=(copy);
189
This is a helper for the assignment operators of implicitly
190
shared classes. Your assignment operator should look like this:
193
MyClass &MyClass:operator=(const MyClass &other)
194
{ qAtomicAssign(d, other.d); return *this; }
197
template <typename T>
198
inline void qAtomicAssign(T *&d, T *x)
201
x = qAtomicSetPtr(&d, x);
209
template <typename T>
210
inline void qAtomicAssign(QBasicAtomicPointer<T> &d, T *x)
221
template <typename T>
222
inline void qAtomicAssign(QBasicAtomicPointer<T> &d, const QBasicAtomicPointer<T> &x)
223
{ qAtomicAssign<T>(d, x); }
226
This is a helper for the detach function. Your private class needs
227
a copy constructor which copies the members and sets the refcount
228
to 1. After that, your detach function should look like this:
231
void MyClass::detach()
232
{ qAtomicDetach(d); }
235
template <typename T>
236
inline void qAtomicDetach(T *&d)
241
x = qAtomicSetPtr(&d, x);
249
template <typename T>
250
inline void qAtomicDetach(QBasicAtomicPointer<T> &d)