Plasma Engine  2.0
Loading...
Searching...
No Matches
AtomicUtils_posix.h
1#ifdef PL_ATOMICUTLS_POSIX_INL_H_INCLUDED
2# error "This file must not be included twice."
3#endif
4
5#define PL_ATOMICUTLS_POSIX_INL_H_INCLUDED
6
7
8#include <Foundation/Math/Math.h>
9
10PL_ALWAYS_INLINE plInt32 plAtomicUtils::Read(const plInt32& src)
11{
12 return __sync_fetch_and_or(const_cast<plInt32*>(&src), 0);
13}
14
15PL_ALWAYS_INLINE plInt64 plAtomicUtils::Read(const plInt64& src)
16{
17 return __sync_fetch_and_or_8(const_cast<plInt64*>(&src), 0);
18}
19
20PL_ALWAYS_INLINE plInt32 plAtomicUtils::Increment(plInt32& dest)
21{
22 return __sync_add_and_fetch(&dest, 1);
23}
24
25PL_ALWAYS_INLINE plInt64 plAtomicUtils::Increment(plInt64& dest)
26{
27 return __sync_add_and_fetch_8(&dest, 1);
28}
29
30
31PL_ALWAYS_INLINE plInt32 plAtomicUtils::Decrement(plInt32& dest)
32{
33 return __sync_sub_and_fetch(&dest, 1);
34}
35
36PL_ALWAYS_INLINE plInt64 plAtomicUtils::Decrement(plInt64& dest)
37{
38 return __sync_sub_and_fetch_8(&dest, 1);
39}
40
41PL_ALWAYS_INLINE plInt32 plAtomicUtils::PostIncrement(plInt32& dest)
42{
43 return __sync_fetch_and_add(&dest, 1);
44}
45
46PL_ALWAYS_INLINE plInt64 plAtomicUtils::PostIncrement(plInt64& dest)
47{
48 return __sync_fetch_and_add_8(&dest, 1);
49}
50
51
52PL_ALWAYS_INLINE plInt32 plAtomicUtils::PostDecrement(plInt32& dest)
53{
54 return __sync_fetch_and_sub(&dest, 1);
55}
56
57PL_ALWAYS_INLINE plInt64 plAtomicUtils::PostDecrement(plInt64& dest)
58{
59 return __sync_fetch_and_sub_8(&dest, 1);
60}
61
62PL_ALWAYS_INLINE void plAtomicUtils::Add(plInt32& dest, plInt32 value)
63{
64 __sync_fetch_and_add(&dest, value);
65}
66
67PL_ALWAYS_INLINE void plAtomicUtils::Add(plInt64& dest, plInt64 value)
68{
69 __sync_fetch_and_add_8(&dest, value);
70}
71
72
73PL_ALWAYS_INLINE void plAtomicUtils::And(plInt32& dest, plInt32 value)
74{
75 __sync_fetch_and_and(&dest, value);
76}
77
78PL_ALWAYS_INLINE void plAtomicUtils::And(plInt64& dest, plInt64 value)
79{
80 __sync_fetch_and_and_8(&dest, value);
81}
82
83
84PL_ALWAYS_INLINE void plAtomicUtils::Or(plInt32& dest, plInt32 value)
85{
86 __sync_fetch_and_or(&dest, value);
87}
88
89PL_ALWAYS_INLINE void plAtomicUtils::Or(plInt64& dest, plInt64 value)
90{
91 __sync_fetch_and_or_8(&dest, value);
92}
93
94
95PL_ALWAYS_INLINE void plAtomicUtils::Xor(plInt32& dest, plInt32 value)
96{
97 __sync_fetch_and_xor(&dest, value);
98}
99
100PL_ALWAYS_INLINE void plAtomicUtils::Xor(plInt64& dest, plInt64 value)
101{
102 __sync_fetch_and_xor_8(&dest, value);
103}
104
105
106PL_FORCE_INLINE void plAtomicUtils::Min(plInt32& dest, plInt32 value)
107{
108 // tries to exchange dest with the new value as long as the oldValue is not what we expected
109 while (true)
110 {
111 plInt32 iOldValue = dest;
112 plInt32 iNewValue = plMath::Min(iOldValue, value);
113
114 if (__sync_bool_compare_and_swap(&dest, iOldValue, iNewValue))
115 break;
116 }
117}
118
119PL_FORCE_INLINE void plAtomicUtils::Min(plInt64& dest, plInt64 value)
120{
121 // tries to exchange dest with the new value as long as the oldValue is not what we expected
122 while (true)
123 {
124 plInt64 iOldValue = dest;
125 plInt64 iNewValue = plMath::Min(iOldValue, value);
126
127 if (__sync_bool_compare_and_swap_8(&dest, iOldValue, iNewValue))
128 break;
129 }
130}
131
132
133PL_FORCE_INLINE void plAtomicUtils::Max(plInt32& dest, plInt32 value)
134{
135 // tries to exchange dest with the new value as long as the oldValue is not what we expected
136 while (true)
137 {
138 plInt32 iOldValue = dest;
139 plInt32 iNewValue = plMath::Max(iOldValue, value);
140
141 if (__sync_bool_compare_and_swap(&dest, iOldValue, iNewValue))
142 break;
143 }
144}
145
146PL_FORCE_INLINE void plAtomicUtils::Max(plInt64& dest, plInt64 value)
147{
148 // tries to exchange dest with the new value as long as the oldValue is not what we expected
149 while (true)
150 {
151 plInt64 iOldValue = dest;
152 plInt64 iNewValue = plMath::Max(iOldValue, value);
153
154 if (__sync_bool_compare_and_swap_8(&dest, iOldValue, iNewValue))
155 break;
156 }
157}
158
159
160PL_ALWAYS_INLINE plInt32 plAtomicUtils::Set(plInt32& dest, plInt32 value)
161{
162 return __sync_lock_test_and_set(&dest, value);
163}
164
165PL_ALWAYS_INLINE plInt64 plAtomicUtils::Set(plInt64& dest, plInt64 value)
166{
167 return __sync_lock_test_and_set_8(&dest, value);
168}
169
170
171PL_ALWAYS_INLINE bool plAtomicUtils::TestAndSet(plInt32& dest, plInt32 expected, plInt32 value)
172{
173 return __sync_bool_compare_and_swap(&dest, expected, value);
174}
175
176PL_ALWAYS_INLINE bool plAtomicUtils::TestAndSet(plInt64& dest, plInt64 expected, plInt64 value)
177{
178 return __sync_bool_compare_and_swap_8(&dest, expected, value);
179}
180
181PL_ALWAYS_INLINE bool plAtomicUtils::TestAndSet(void** dest, void* expected, void* value)
182{
183#if PL_ENABLED(PL_PLATFORM_64BIT)
184 plUInt64* puiTemp = reinterpret_cast<plUInt64*>(dest);
185 return __sync_bool_compare_and_swap(puiTemp, reinterpret_cast<plUInt64>(expected), reinterpret_cast<plUInt64>(value));
186#else
187 plUInt32* puiTemp = reinterpret_cast<plUInt32*>(dest);
188 return __sync_bool_compare_and_swap(puiTemp, reinterpret_cast<plUInt32>(expected), reinterpret_cast<plUInt32>(value));
189#endif
190}
191
192PL_ALWAYS_INLINE plInt32 plAtomicUtils::CompareAndSwap(plInt32& dest, plInt32 expected, plInt32 value)
193{
194 return __sync_val_compare_and_swap(&dest, expected, value);
195}
196
197PL_ALWAYS_INLINE plInt64 plAtomicUtils::CompareAndSwap(plInt64& dest, plInt64 expected, plInt64 value)
198{
199 return __sync_val_compare_and_swap_8(&dest, expected, value);
200}
constexpr PL_ALWAYS_INLINE T Min(T f1, T f2)
Returns the smaller value, f1 or f2.
Definition Math_inl.h:27
constexpr PL_ALWAYS_INLINE T Max(T f1, T f2)
Returns the greater value, f1 or f2.
Definition Math_inl.h:39
static plInt32 Decrement(plInt32 &ref_iDest)
Decrements dest as an atomic operation and returns the new value.
Definition AtomicUtils_posix.h:31
static void Add(plInt32 &ref_iDest, plInt32 value)
Adds value to dest as an atomic operation.
Definition AtomicUtils_posix.h:62
static plInt32 CompareAndSwap(plInt32 &ref_iDest, plInt32 iExpected, plInt32 value)
If dest is equal to expected, this function sets dest to value. Otherwise dest will not be modified....
Definition AtomicUtils_posix.h:192
static void Or(plInt32 &ref_iDest, plInt32 value)
Performs an atomic bitwise OR on dest using value.
Definition AtomicUtils_posix.h:84
static plInt32 Read(const plInt32 &iSrc)
Returns src as an atomic operation and returns its value.
Definition AtomicUtils_posix.h:10
static void Min(plInt32 &ref_iDest, plInt32 value)
Performs an atomic min operation on dest using value.
Definition AtomicUtils_posix.h:106
static void And(plInt32 &ref_iDest, plInt32 value)
Performs an atomic bitwise AND on dest using value.
Definition AtomicUtils_posix.h:73
static void Xor(plInt32 &ref_iDest, plInt32 value)
Performs an atomic bitwise XOR on dest using value.
Definition AtomicUtils_posix.h:95
static plInt32 PostIncrement(plInt32 &ref_iDest)
Increments dest as an atomic operation and returns the old value.
Definition AtomicUtils_posix.h:41
static plInt32 Increment(plInt32 &ref_iDest)
Increments dest as an atomic operation and returns the new value.
Definition AtomicUtils_posix.h:20
static void Max(plInt32 &ref_iDest, plInt32 value)
Performs an atomic max operation on dest using value.
Definition AtomicUtils_posix.h:133
static plInt32 PostDecrement(plInt32 &ref_iDest)
Decrements dest as an atomic operation and returns the old value.
Definition AtomicUtils_posix.h:52
static plInt32 Set(plInt32 &ref_iDest, plInt32 value)
Sets dest to value as an atomic operation and returns the original value of dest.
Definition AtomicUtils_posix.h:160
static bool TestAndSet(plInt32 &ref_iDest, plInt32 iExpected, plInt32 value)
If dest is equal to expected, this function sets dest to value and returns true. Otherwise dest will ...
Definition AtomicUtils_posix.h:171