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