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
ZyanAtomicCompareExchange(ZyanAtomicPointer * destination,ZyanUPointer comparand,ZyanUPointer value)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
ZyanAtomicIncrement(ZyanAtomicPointer * destination)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
ZyanAtomicDecrement(ZyanAtomicPointer * destination)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
ZyanAtomicCompareExchange32(ZyanAtomic32 * destination,ZyanU32 comparand,ZyanU32 value)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
ZyanAtomicIncrement32(ZyanAtomic32 * destination)76 ZYAN_INLINE ZyanU32 ZyanAtomicIncrement32(ZyanAtomic32* destination)
77 {
78 return (ZyanU32)(__sync_fetch_and_add(&destination->value, 1, &destination->value)) + 1;
79 }
80
ZyanAtomicDecrement32(ZyanAtomic32 * destination)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
ZyanAtomicCompareExchange64(ZyanAtomic64 * destination,ZyanU64 comparand,ZyanU64 value)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
ZyanAtomicIncrement64(ZyanAtomic64 * destination)97 ZYAN_INLINE ZyanU64 ZyanAtomicIncrement64(ZyanAtomic64* destination)
98 {
99 return (ZyanU64)(__sync_fetch_and_add(&destination->value, 1, &destination->value)) + 1;
100 }
101
ZyanAtomicDecrement64(ZyanAtomic64 * destination)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