xref: /haiku/headers/libs/zydis/Zycore/Internal/AtomicGNU.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 #ifndef ZYCORE_ATOMIC_GNU_H
28 #define ZYCORE_ATOMIC_GNU_H
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 #include <Zycore/Defines.h>
35 #include <Zycore/Types.h>
36 
37 /* ============================================================================================== */
38 /* Functions                                                                                      */
39 /* ============================================================================================== */
40 
41 #if defined(ZYAN_CLANG) || defined(ZYAN_GCC) || defined(ZYAN_ICC)
42 
43 /* ---------------------------------------------------------------------------------------------- */
44 /* Pointer sized                                                                                  */
45 /* ---------------------------------------------------------------------------------------------- */
46 
47 ZYAN_INLINE ZyanUPointer ZyanAtomicCompareExchange(ZyanAtomicPointer* destination,
48     ZyanUPointer comparand, ZyanUPointer value)
49 {
50     return (ZyanUPointer)(__sync_val_compare_and_swap(
51         &destination->value, (void*)comparand, (void*)value, &destination->value));
52 }
53 
54 ZYAN_INLINE ZyanUPointer ZyanAtomicIncrement(ZyanAtomicPointer* destination)
55 {
56     return (ZyanUPointer)(__sync_fetch_and_add(&destination->value, (void*)1,
57         &destination->value)) + 1;
58 }
59 
60 ZYAN_INLINE ZyanUPointer ZyanAtomicDecrement(ZyanAtomicPointer* destination)
61 {
62     return (ZyanUPointer)(__sync_sub_and_fetch(&destination->value, (void*)1, &destination->value));
63 }
64 
65 /* ---------------------------------------------------------------------------------------------- */
66 /* 32-bit                                                                                         */
67 /* ---------------------------------------------------------------------------------------------- */
68 
69 ZYAN_INLINE ZyanU32 ZyanAtomicCompareExchange32(ZyanAtomic32* destination,
70     ZyanU32 comparand, ZyanU32 value)
71 {
72     return (ZyanU32)(__sync_val_compare_and_swap(&destination->value, comparand, value,
73         &destination->value));
74 }
75 
76 ZYAN_INLINE ZyanU32 ZyanAtomicIncrement32(ZyanAtomic32* destination)
77 {
78     return (ZyanU32)(__sync_fetch_and_add(&destination->value, 1, &destination->value)) + 1;
79 }
80 
81 ZYAN_INLINE ZyanU32 ZyanAtomicDecrement32(ZyanAtomic32* destination)
82 {
83     return (ZyanU32)(__sync_sub_and_fetch(&destination->value, 1, &destination->value));
84 }
85 
86 /* ---------------------------------------------------------------------------------------------- */
87 /* 64-bit                                                                                         */
88 /* ---------------------------------------------------------------------------------------------- */
89 
90 ZYAN_INLINE ZyanU64 ZyanAtomicCompareExchange64(ZyanAtomic64* destination,
91     ZyanU64 comparand, ZyanU64 value)
92 {
93     return (ZyanU64)(__sync_val_compare_and_swap(&destination->value, comparand, value,
94         &destination->value));
95 }
96 
97 ZYAN_INLINE ZyanU64 ZyanAtomicIncrement64(ZyanAtomic64* destination)
98 {
99     return (ZyanU64)(__sync_fetch_and_add(&destination->value, 1, &destination->value)) + 1;
100 }
101 
102 ZYAN_INLINE ZyanU64 ZyanAtomicDecrement64(ZyanAtomic64* destination)
103 {
104     return (ZyanU64)(__sync_sub_and_fetch(&destination->value, 1, &destination->value));
105 }
106 
107 /* ---------------------------------------------------------------------------------------------- */
108 
109 #endif
110 
111 /* ============================================================================================== */
112 
113 #ifdef __cplusplus
114 }
115 #endif
116 
117 #endif /* ZYCORE_ATOMIC_GNU_H */
118