1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: functions to manipulate atomically integers and pointers
4 // Author: Armel Asselin
7 // Copyright: (c) Armel Asselin
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
18 // get the value of wxUSE_THREADS configuration flag
21 // constraints on the various functions:
22 // - wxAtomicDec must return a zero value if the value is zero once
23 // decremented else it must return any non-zero value (the true value is OK
24 // but not necessary).
28 #if defined(__WXMSW__)
30 // include standard Windows headers
31 #include "wx/msw/wrapwin.h"
33 inline void wxAtomicInc (wxUint32
&value
)
35 InterlockedIncrement ((LONG
*)&value
);
38 inline wxUint32
wxAtomicDec (wxUint32
&value
)
40 return InterlockedDecrement ((LONG
*)&value
);
43 #elif defined(__WXMAC__) || defined(__DARWIN__)
45 #include "libkern/OSAtomic.h"
46 inline void wxAtomicInc (wxUint32
&value
)
48 OSAtomicIncrement32 ((int32_t*)&value
);
51 inline wxUint32
wxAtomicDec (wxUint32
&value
)
53 return OSAtomicDecrement32 ((int32_t*)&value
);
56 #elif defined(__LINUX__)
58 #include <asm/atomic.h>
60 inline void wxAtomicInc (wxUint32
&value
)
62 atomic_inc ((atomic_t
*)&value
);
65 inline wxUint32
wxAtomicDec (wxUint32
&value
)
67 return atomic_dec_and_test ((atomic_t
*)&value
) ? 0 : 1;
70 #elif defined (__SOLARIS__)
74 inline void wxAtomicInc (wxUint32
&value
)
76 atomic_add_32 ((uint32_t*)&value
, 1);
79 inline wxUint32
wxAtomicDec (wxUint32
&value
)
81 return atomic_add_32_nv ((uint32_t*)&value
, (uint32_t)-1);
84 #else // unknown platform
86 // it will result in inclusion if the generic implementation code a bit later in this page
87 #define wxHAS_GENERIC_ATOMIC_OPS 1
89 #endif // unknown platform
91 #else // else of wxUSE_THREADS
92 // if no threads are used we can safely use simple ++/--
94 inline void wxAtomicInc (wxUint32
&value
) { ++value
; }
95 inline wxUint32
wxAtomicDec (wxUint32
&value
) { return --value
; }
97 #endif // !wxUSE_THREADS
99 // ----------------------------------------------------------------------------
100 // proxies to actual implementations, but for various other types with same
102 // ----------------------------------------------------------------------------
104 #if !defined(wxHAS_GENERIC_ATOMIC_OPS)
105 #define wxHAS_GENERIC_ATOMIC_OPS 0
108 #if wxHAS_GENERIC_ATOMIC_OPS
109 #include "wx/thread.h" // for wxCriticalSection
114 wxAtomicInt32() { } // non initialized for consistency with basic int type
115 wxAtomicInt32(wxInt32 v
) : m_value(v
) { }
116 wxAtomicInt32(const wxAtomicInt32
& a
) : m_value(a
.m_value
) {}
118 operator wxInt32() const { return m_value
; }
119 operator volatile wxInt32
&() { return m_value
; }
121 wxAtomicInt32
& operator=(wxInt32 v
) { m_value
= v
; return *this; }
125 wxCriticalSectionLocker
lock(m_locker
);
131 wxCriticalSectionLocker
lock(m_locker
);
136 volatile wxInt32 m_value
;
137 wxCriticalSection m_locker
;
140 inline void wxAtomicInc(wxAtomicInt32
&value
) { value
.Inc(); }
141 inline wxInt32
wxAtomicDec(wxAtomicInt32
&value
) { return value
.Dec(); }
143 #else // !wxHAS_GENERIC_ATOMIC_OPS
145 inline void wxAtomicInc(wxInt32
&value
) { wxAtomicInc((wxUint32
&)value
); }
146 inline wxInt32
wxAtomicDec(wxInt32
&value
) { return wxAtomicDec((wxUint32
&)value
); }
148 typedef wxInt32 wxAtomicInt32
;
150 #endif // wxHAS_GENERIC_ATOMIC_OPS
152 // all the native implementations use 32 bits currently
153 // for a 64 bits implementation we could use (a future) wxAtomicInt64 as
155 typedef wxAtomicInt32 wxAtomicInt
;
157 #endif // _WX_ATOMIC_H_