xref: /haiku/headers/libs/zydis/Zycore/Atomic.h (revision 1003e004e6c97eb60657a98928dd334e141c59ee)
1*1003e004SJérôme Duval /***************************************************************************************************
2*1003e004SJérôme Duval 
3*1003e004SJérôme Duval   Zyan Core Library (Zyan-C)
4*1003e004SJérôme Duval 
5*1003e004SJérôme Duval   Original Author : Florian Bernd
6*1003e004SJérôme Duval 
7*1003e004SJérôme Duval  * Permission is hereby granted, free of charge, to any person obtaining a copy
8*1003e004SJérôme Duval  * of this software and associated documentation files (the "Software"), to deal
9*1003e004SJérôme Duval  * in the Software without restriction, including without limitation the rights
10*1003e004SJérôme Duval  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11*1003e004SJérôme Duval  * copies of the Software, and to permit persons to whom the Software is
12*1003e004SJérôme Duval  * furnished to do so, subject to the following conditions:
13*1003e004SJérôme Duval  *
14*1003e004SJérôme Duval  * The above copyright notice and this permission notice shall be included in all
15*1003e004SJérôme Duval  * copies or substantial portions of the Software.
16*1003e004SJérôme Duval  *
17*1003e004SJérôme Duval  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18*1003e004SJérôme Duval  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*1003e004SJérôme Duval  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20*1003e004SJérôme Duval  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21*1003e004SJérôme Duval  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22*1003e004SJérôme Duval  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23*1003e004SJérôme Duval  * SOFTWARE.
24*1003e004SJérôme Duval 
25*1003e004SJérôme Duval ***************************************************************************************************/
26*1003e004SJérôme Duval 
27*1003e004SJérôme Duval /**
28*1003e004SJérôme Duval  * @file
29*1003e004SJérôme Duval  * Cross compiler atomic intrinsics.
30*1003e004SJérôme Duval  */
31*1003e004SJérôme Duval 
32*1003e004SJérôme Duval #ifndef ZYCORE_ATOMIC_H
33*1003e004SJérôme Duval #define ZYCORE_ATOMIC_H
34*1003e004SJérôme Duval 
35*1003e004SJérôme Duval #ifdef __cplusplus
36*1003e004SJérôme Duval extern "C" {
37*1003e004SJérôme Duval #endif
38*1003e004SJérôme Duval 
39*1003e004SJérôme Duval #include <Zycore/Defines.h>
40*1003e004SJérôme Duval #include <Zycore/Types.h>
41*1003e004SJérôme Duval 
42*1003e004SJérôme Duval /* ============================================================================================== */
43*1003e004SJérôme Duval /* Enums and Types                                                                                */
44*1003e004SJérôme Duval /* ============================================================================================== */
45*1003e004SJérôme Duval 
46*1003e004SJérôme Duval /*
47*1003e004SJérôme Duval  * Wraps a 32-bit value to provide atomic access.
48*1003e004SJérôme Duval  */
49*1003e004SJérôme Duval typedef struct ZyanAtomic32_
50*1003e004SJérôme Duval {
51*1003e004SJérôme Duval     ZyanU32 volatile value;
52*1003e004SJérôme Duval } ZyanAtomic32;
53*1003e004SJérôme Duval 
54*1003e004SJérôme Duval /*
55*1003e004SJérôme Duval  * Wraps a 64-bit value to provide atomic access.
56*1003e004SJérôme Duval  */
57*1003e004SJérôme Duval typedef struct ZyanAtomic64_
58*1003e004SJérôme Duval {
59*1003e004SJérôme Duval     ZyanU64 volatile value;
60*1003e004SJérôme Duval } ZyanAtomic64;
61*1003e004SJérôme Duval 
62*1003e004SJérôme Duval /*
63*1003e004SJérôme Duval  * Wraps a pointer-sized value to provide atomic access.
64*1003e004SJérôme Duval  */
65*1003e004SJérôme Duval typedef struct ZyanAtomicPointer_
66*1003e004SJérôme Duval {
67*1003e004SJérôme Duval     ZyanVoidPointer volatile value;
68*1003e004SJérôme Duval } ZyanAtomicPointer;
69*1003e004SJérôme Duval 
70*1003e004SJérôme Duval /* ============================================================================================== */
71*1003e004SJérôme Duval /* Macros                                                                                         */
72*1003e004SJérôme Duval /* ============================================================================================== */
73*1003e004SJérôme Duval 
74*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
75*1003e004SJérôme Duval /* Pointer sized                                                                                  */
76*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
77*1003e004SJérôme Duval 
78*1003e004SJérôme Duval /**
79*1003e004SJérôme Duval  * @copydoc ZyanAtomicCompareExchange
80*1003e004SJérôme Duval  */
81*1003e004SJérôme Duval #define ZYAN_ATOMIC_COMPARE_EXCHANGE(destination, comparand, value) \
82*1003e004SJérôme Duval     ZyanAtomicCompareExchange((ZyanAtomicPointer*)&(destination), (comparand), (value))
83*1003e004SJérôme Duval 
84*1003e004SJérôme Duval /**
85*1003e004SJérôme Duval  * @copydoc ZyanAtomicIncrement
86*1003e004SJérôme Duval  */
87*1003e004SJérôme Duval #define ZYAN_ATOMIC_INCREMENT(destination) \
88*1003e004SJérôme Duval     ZyanAtomicIncrement((ZyanAtomicPointer*)&(destination));
89*1003e004SJérôme Duval 
90*1003e004SJérôme Duval /**
91*1003e004SJérôme Duval  * @copydoc ZyanAtomicDecrement
92*1003e004SJérôme Duval  */
93*1003e004SJérôme Duval #define ZYAN_ATOMIC_DECREMENT(destination) \
94*1003e004SJérôme Duval     ZyanAtomicDecrement((ZyanAtomicPointer*)&(destination));
95*1003e004SJérôme Duval 
96*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
97*1003e004SJérôme Duval /* 32-bit                                                                                         */
98*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
99*1003e004SJérôme Duval 
100*1003e004SJérôme Duval /**
101*1003e004SJérôme Duval  * @copydoc ZyanAtomicCompareExchange
102*1003e004SJérôme Duval  */
103*1003e004SJérôme Duval #define ZYAN_ATOMIC_COMPARE_EXCHANGE32(destination, comparand, value) \
104*1003e004SJérôme Duval     ZyanAtomicCompareExchange32((ZyanAtomic32*)&(destination), (comparand), (value))
105*1003e004SJérôme Duval 
106*1003e004SJérôme Duval /**
107*1003e004SJérôme Duval  * @copydoc ZyanAtomicIncrement
108*1003e004SJérôme Duval  */
109*1003e004SJérôme Duval #define ZYAN_ATOMIC_INCREMENT32(destination) \
110*1003e004SJérôme Duval     ZyanAtomicIncrement32((ZyanAtomic32*)&(destination));
111*1003e004SJérôme Duval 
112*1003e004SJérôme Duval /**
113*1003e004SJérôme Duval  * @copydoc ZyanAtomicDecrement
114*1003e004SJérôme Duval  */
115*1003e004SJérôme Duval #define ZYAN_ATOMIC_DECREMENT32(destination) \
116*1003e004SJérôme Duval     ZyanAtomicDecrement32((ZyanAtomic32*)&(destination));
117*1003e004SJérôme Duval 
118*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
119*1003e004SJérôme Duval /* 64-bit                                                                                         */
120*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
121*1003e004SJérôme Duval 
122*1003e004SJérôme Duval /**
123*1003e004SJérôme Duval  * @copydoc ZyanAtomicCompareExchange
124*1003e004SJérôme Duval  */
125*1003e004SJérôme Duval #define ZYAN_ATOMIC_COMPARE_EXCHANGE64(destination, comparand, value) \
126*1003e004SJérôme Duval     ZyanAtomicCompareExchange64((ZyanAtomic64*)&(destination), (comparand), (value))
127*1003e004SJérôme Duval 
128*1003e004SJérôme Duval /**
129*1003e004SJérôme Duval  * @copydoc ZyanAtomicIncrement
130*1003e004SJérôme Duval  */
131*1003e004SJérôme Duval #define ZYAN_ATOMIC_INCREMENT64(destination) \
132*1003e004SJérôme Duval     ZyanAtomicIncrement64((ZyanAtomic64*)&(destination));
133*1003e004SJérôme Duval 
134*1003e004SJérôme Duval /**
135*1003e004SJérôme Duval  * @copydoc ZyanAtomicDecrement
136*1003e004SJérôme Duval  */
137*1003e004SJérôme Duval #define ZYAN_ATOMIC_DECREMENT64(destination) \
138*1003e004SJérôme Duval     ZyanAtomicDecrement64((ZyanAtomic64*)&(destination));
139*1003e004SJérôme Duval 
140*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
141*1003e004SJérôme Duval 
142*1003e004SJérôme Duval /* ============================================================================================== */
143*1003e004SJérôme Duval /* Functions                                                                                      */
144*1003e004SJérôme Duval /* ============================================================================================== */
145*1003e004SJérôme Duval 
146*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
147*1003e004SJérôme Duval /* Pointer sized                                                                                  */
148*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
149*1003e004SJérôme Duval 
150*1003e004SJérôme Duval /**
151*1003e004SJérôme Duval  * Compares two values for equality and, if they are equal, replaces the first value.
152*1003e004SJérôme Duval  *
153*1003e004SJérôme Duval  * @param   destination A pointer to the destination value.
154*1003e004SJérôme Duval  * @param   comparand   The value to compare with.
155*1003e004SJérôme Duval  * @param   value       The replacement value.
156*1003e004SJérôme Duval  *
157*1003e004SJérôme Duval  * @return  The original value.
158*1003e004SJérôme Duval  */
159*1003e004SJérôme Duval static ZyanUPointer ZyanAtomicCompareExchange(ZyanAtomicPointer* destination,
160*1003e004SJérôme Duval     ZyanUPointer comparand, ZyanUPointer value);
161*1003e004SJérôme Duval 
162*1003e004SJérôme Duval /**
163*1003e004SJérôme Duval  * Increments the given value and stores the result, as an atomic operation.
164*1003e004SJérôme Duval  *
165*1003e004SJérôme Duval  * @param   destination A pointer to the destination value.
166*1003e004SJérôme Duval  *
167*1003e004SJérôme Duval  * @return  The incremented value.
168*1003e004SJérôme Duval */
169*1003e004SJérôme Duval static ZyanUPointer ZyanAtomicIncrement(ZyanAtomicPointer* destination);
170*1003e004SJérôme Duval 
171*1003e004SJérôme Duval /**
172*1003e004SJérôme Duval  * Decrements the given value and stores the result, as an atomic operation.
173*1003e004SJérôme Duval  *
174*1003e004SJérôme Duval  * @param   destination A pointer to the destination value.
175*1003e004SJérôme Duval  *
176*1003e004SJérôme Duval  * @return  The decremented value.
177*1003e004SJérôme Duval */
178*1003e004SJérôme Duval static ZyanUPointer ZyanAtomicDecrement(ZyanAtomicPointer* destination);
179*1003e004SJérôme Duval 
180*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
181*1003e004SJérôme Duval /* 32-bit                                                                                         */
182*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
183*1003e004SJérôme Duval 
184*1003e004SJérôme Duval /**
185*1003e004SJérôme Duval  * @copydoc ZyanAtomicCompareExchange
186*1003e004SJérôme Duval  */
187*1003e004SJérôme Duval static ZyanU32 ZyanAtomicCompareExchange32(ZyanAtomic32* destination,
188*1003e004SJérôme Duval     ZyanU32 comparand, ZyanU32 value);
189*1003e004SJérôme Duval 
190*1003e004SJérôme Duval /**
191*1003e004SJérôme Duval  * @copydoc ZyanAtomicIncrement
192*1003e004SJérôme Duval  */
193*1003e004SJérôme Duval static ZyanU32 ZyanAtomicIncrement32(ZyanAtomic32* destination);
194*1003e004SJérôme Duval 
195*1003e004SJérôme Duval /**
196*1003e004SJérôme Duval  * @copydoc ZyanAtomicDecrement
197*1003e004SJérôme Duval  */
198*1003e004SJérôme Duval static ZyanU32 ZyanAtomicDecrement32(ZyanAtomic32* destination);
199*1003e004SJérôme Duval 
200*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
201*1003e004SJérôme Duval /* 64-bit                                                                                         */
202*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
203*1003e004SJérôme Duval 
204*1003e004SJérôme Duval /**
205*1003e004SJérôme Duval  * @copydoc ZyanAtomicCompareExchange
206*1003e004SJérôme Duval  */
207*1003e004SJérôme Duval static ZyanU64 ZyanAtomicCompareExchange64(ZyanAtomic64* destination,
208*1003e004SJérôme Duval     ZyanU64 comparand, ZyanU64 value);
209*1003e004SJérôme Duval 
210*1003e004SJérôme Duval /**
211*1003e004SJérôme Duval  * @copydoc ZyanAtomicIncrement
212*1003e004SJérôme Duval  */
213*1003e004SJérôme Duval static ZyanU64 ZyanAtomicIncrement64(ZyanAtomic64* destination);
214*1003e004SJérôme Duval 
215*1003e004SJérôme Duval /**
216*1003e004SJérôme Duval  * @copydoc ZyanAtomicDecrement
217*1003e004SJérôme Duval  */
218*1003e004SJérôme Duval static ZyanU64 ZyanAtomicDecrement64(ZyanAtomic64* destination);
219*1003e004SJérôme Duval 
220*1003e004SJérôme Duval /* ---------------------------------------------------------------------------------------------- */
221*1003e004SJérôme Duval 
222*1003e004SJérôme Duval /* ============================================================================================== */
223*1003e004SJérôme Duval 
224*1003e004SJérôme Duval #if defined(ZYAN_CLANG) || defined(ZYAN_GCC) || defined(ZYAN_ICC)
225*1003e004SJérôme Duval #   include <Zycore/Internal/AtomicGNU.h>
226*1003e004SJérôme Duval #elif defined(ZYAN_MSVC)
227*1003e004SJérôme Duval #   include <Zycore/Internal/AtomicMSVC.h>
228*1003e004SJérôme Duval #else
229*1003e004SJérôme Duval #   error "Unsupported compiler detected"
230*1003e004SJérôme Duval #endif
231*1003e004SJérôme Duval 
232*1003e004SJérôme Duval #ifdef __cplusplus
233*1003e004SJérôme Duval }
234*1003e004SJérôme Duval #endif
235*1003e004SJérôme Duval 
236*1003e004SJérôme Duval #endif /* ZYCORE_ATOMIC_H */
237