@@ -25,262 +25,7 @@ F/MonoDroid( 1568): shared runtime initialization error: Cannot load library: re
2525Apple targets have historically being problematic, xcode 4.6 would miscompile the intrinsic.
2626*/
2727
28- /* Decide if we will use stdatomic.h */
29- /*
30- * Generally, we can enable C11 atomics if the header is available and if all the primitive types we
31- * care about (int, long, void*, long long) are lock-free.
32- *
33- * Note that we generally don't want the compiler's locking implementation because it may take a
34- * global lock, in which case if the atomic is used by both the GC implementation and runtime
35- * internals we may have deadlocks during GC suspend.
36- *
37- * It might be possible to use some Mono specific implementation for specific types (e.g. long long)
38- * on some platforms if the standard atomics for some type are not lock-free (for example: long
39- * long). We might be able to use a GC-aware lock, for example.
40- *
41- */
42- #if defined(_MSC_VER )
43- /*
44- * we need two things:
45- *
46- * 1. MSVC atomics support is not experimental, or we pass /experimental:c11atomics
47- *
48- * 2. We build our C++ code with C++23 or later (otherwise MSVC will complain about including
49- * stdatomic.h)
50- *
51- */
52- # undef MONO_USE_STDATOMIC
53- #elif defined(HOST_IOS ) || defined(HOST_OSX ) || defined(HOST_WATCHOS ) || defined(HOST_TVOS )
54- # define MONO_USE_STDATOMIC 1
55- #elif defined(HOST_ANDROID )
56- /* on Android-x86 ATOMIC_LONG_LONG_LOCK_FREE == 1, not 2 like we want. */
57- /* on Andriod-x64 ATOMIC_LONG_LOCK_FREE == 1, not 2 */
58- /* on Android-armv7 ATOMIC_INT_LOCK_FREE == 1, not 2 */
59- # if defined(HOST_ARM64 )
60- # define MONO_USE_STDATOMIC 1
61- # endif
62- #elif defined(HOST_LINUX )
63- /* FIXME: probably need arch checks */
64- # define MONO_USE_STDATOMIC 1
65- #elif defined(HOST_WASI ) || defined(HOST_BROWSER )
66- # define MONO_USE_STDATOMIC 1
67- #else
68- # undef MONO_USE_STDATOMIC
69- #endif
70-
71- #ifdef MONO_USE_STDATOMIC
72-
73- #include <stdatomic.h>
74-
75- static inline gint32
76- mono_atomic_cas_i32 (volatile gint32 * dest , gint32 exch , gint32 comp )
77- {
78- g_static_assert (sizeof (atomic_int ) == sizeof (* dest ) && ATOMIC_INT_LOCK_FREE == 2 );
79- (void )atomic_compare_exchange_strong ((volatile atomic_int * )dest , & comp , exch );
80- return comp ;
81- }
82-
83- static inline gint64
84- mono_atomic_cas_i64 (volatile gint64 * dest , gint64 exch , gint64 comp )
85- {
86- #if SIZEOF_LONG == 8
87- g_static_assert (sizeof (atomic_long ) == sizeof (* dest ) && ATOMIC_LONG_LOCK_FREE == 2 );
88- (void )atomic_compare_exchange_strong ((volatile atomic_long * )dest , (long * )& comp , exch );
89- return comp ;
90- #elif SIZEOF_LONG_LONG == 8
91- g_static_assert (sizeof (atomic_llong ) == sizeof (* dest ) && ATOMIC_LLONG_LOCK_FREE == 2 );
92- (void )atomic_compare_exchange_strong ((volatile atomic_llong * )dest , (long long * )& comp , exch );
93- return comp ;
94- #else
95- #error gint64 not same size atomic_llong or atomic_long, don't define MONO_USE_STDATOMIC
96- #endif
97- }
98-
99- static inline gpointer
100- mono_atomic_cas_ptr (volatile gpointer * dest , gpointer exch , gpointer comp )
101- {
102- g_static_assert (ATOMIC_POINTER_LOCK_FREE == 2 );
103- (void )atomic_compare_exchange_strong ((volatile _Atomic (gpointer ) * )dest , & comp , exch );
104- return comp ;
105- }
106-
107- static inline gint32
108- mono_atomic_fetch_add_i32 (volatile gint32 * dest , gint32 add );
109- static inline gint64
110- mono_atomic_fetch_add_i64 (volatile gint64 * dest , gint64 add );
111-
112- static inline gint32
113- mono_atomic_add_i32 (volatile gint32 * dest , gint32 add )
114- {
115- // mono_atomic_add_ is supposed to return the value that is stored.
116- // the atomic_add intrinsic returns the previous value instead.
117- // so we return prev+add which should be the new value
118- return mono_atomic_fetch_add_i32 (dest , add ) + add ;
119- }
120-
121- static inline gint64
122- mono_atomic_add_i64 (volatile gint64 * dest , gint64 add )
123- {
124- return mono_atomic_fetch_add_i64 (dest , add ) + add ;
125- }
126-
127- static inline gint32
128- mono_atomic_inc_i32 (volatile gint32 * dest )
129- {
130- return mono_atomic_add_i32 (dest , 1 );
131- }
132-
133- static inline gint64
134- mono_atomic_inc_i64 (volatile gint64 * dest )
135- {
136- return mono_atomic_add_i64 (dest , 1 );
137- }
138-
139- static inline gint32
140- mono_atomic_dec_i32 (volatile gint32 * dest )
141- {
142- return mono_atomic_add_i32 (dest , -1 );
143- }
144-
145- static inline gint64
146- mono_atomic_dec_i64 (volatile gint64 * dest )
147- {
148- return mono_atomic_add_i64 (dest , -1 );
149- }
150-
151- static inline gint32
152- mono_atomic_xchg_i32 (volatile gint32 * dest , gint32 exch )
153- {
154- g_static_assert (sizeof (atomic_int ) == sizeof (* dest ) && ATOMIC_INT_LOCK_FREE == 2 );
155- return atomic_exchange ((volatile atomic_int * )dest , exch );
156- }
157-
158- static inline gint64
159- mono_atomic_xchg_i64 (volatile gint64 * dest , gint64 exch )
160- {
161- #if SIZEOF_LONG == 8
162- g_static_assert (sizeof (atomic_long ) == sizeof (* dest ) && ATOMIC_LONG_LOCK_FREE == 2 );
163- return atomic_exchange ((volatile atomic_long * )dest , exch );
164- #elif SIZEOF_LONG_LONG == 8
165- g_static_assert (sizeof (atomic_llong ) == sizeof (* dest ) && ATOMIC_LLONG_LOCK_FREE == 2 );
166- return atomic_exchange ((volatile atomic_llong * )dest , exch );
167- #else
168- #error gint64 not same size atomic_llong or atomic_long, don't define MONO_USE_STDATOMIC
169- #endif
170- }
171-
172- static inline gpointer
173- mono_atomic_xchg_ptr (volatile gpointer * dest , gpointer exch )
174- {
175- g_static_assert (ATOMIC_POINTER_LOCK_FREE == 2 );
176- return atomic_exchange ((volatile _Atomic (gpointer ) * )dest , exch );
177- }
178-
179- static inline gint32
180- mono_atomic_fetch_add_i32 (volatile gint32 * dest , gint32 add )
181- {
182- g_static_assert (sizeof (atomic_int ) == sizeof (* dest ) && ATOMIC_INT_LOCK_FREE == 2 );
183- return atomic_fetch_add ((volatile atomic_int * )dest , add );
184- }
185-
186- static inline gint64
187- mono_atomic_fetch_add_i64 (volatile gint64 * dest , gint64 add )
188- {
189- #if SIZEOF_LONG == 8
190- g_static_assert (sizeof (atomic_long ) == sizeof (* dest ) && ATOMIC_LONG_LOCK_FREE == 2 );
191- return atomic_fetch_add ((volatile atomic_long * )dest , add );
192- #elif SIZEOF_LONG_LONG == 8
193- g_static_assert (sizeof (atomic_llong ) == sizeof (* dest ) && ATOMIC_LLONG_LOCK_FREE == 2 );
194- return atomic_fetch_add ((volatile atomic_llong * )dest , add );
195- #else
196- #error gint64 not same size atomic_llong or atomic_long, don't define MONO_USE_STDATOMIC
197- #endif
198- }
199-
200- static inline gint8
201- mono_atomic_load_i8 (volatile gint8 * src )
202- {
203- g_static_assert (sizeof (atomic_char ) == sizeof (* src ) && ATOMIC_CHAR_LOCK_FREE == 2 );
204- return atomic_load ((volatile atomic_char * )src );
205- }
206-
207- static inline gint16
208- mono_atomic_load_i16 (volatile gint16 * src )
209- {
210- g_static_assert (sizeof (atomic_short ) == sizeof (* src ) && ATOMIC_SHORT_LOCK_FREE == 2 );
211- return atomic_load ((volatile atomic_short * )src );
212- }
213-
214- static inline gint32 mono_atomic_load_i32 (volatile gint32 * src )
215- {
216- g_static_assert (sizeof (atomic_int ) == sizeof (* src ) && ATOMIC_INT_LOCK_FREE == 2 );
217- return atomic_load ((volatile atomic_int * )src );
218- }
219-
220- static inline gint64
221- mono_atomic_load_i64 (volatile gint64 * src )
222- {
223- #if SIZEOF_LONG == 8
224- g_static_assert (sizeof (atomic_long ) == sizeof (* src ) && ATOMIC_LONG_LOCK_FREE == 2 );
225- return atomic_load ((volatile atomic_long * )src );
226- #elif SIZEOF_LONG_LONG == 8
227- g_static_assert (sizeof (atomic_llong ) == sizeof (* src ) && ATOMIC_LLONG_LOCK_FREE == 2 );
228- return atomic_load ((volatile atomic_llong * )src );
229- #else
230- #error gint64 not same size atomic_llong or atomic_long, don't define MONO_USE_STDATOMIC
231- #endif
232- }
233-
234- static inline gpointer
235- mono_atomic_load_ptr (volatile gpointer * src )
236- {
237- g_static_assert (ATOMIC_POINTER_LOCK_FREE == 2 );
238- return atomic_load ((volatile _Atomic (gpointer ) * )src );
239- }
240-
241- static inline void
242- mono_atomic_store_i8 (volatile gint8 * dst , gint8 val )
243- {
244- g_static_assert (sizeof (atomic_char ) == sizeof (* dst ) && ATOMIC_CHAR_LOCK_FREE == 2 );
245- atomic_store ((volatile atomic_char * )dst , val );
246- }
247-
248- static inline void
249- mono_atomic_store_i16 (volatile gint16 * dst , gint16 val )
250- {
251- g_static_assert (sizeof (atomic_short ) == sizeof (* dst ) && ATOMIC_SHORT_LOCK_FREE == 2 );
252- atomic_store ((volatile atomic_short * )dst , val );
253- }
254-
255- static inline void
256- mono_atomic_store_i32 (volatile gint32 * dst , gint32 val )
257- {
258- g_static_assert (sizeof (atomic_int ) == sizeof (* dst ) && ATOMIC_INT_LOCK_FREE == 2 );
259- atomic_store ((atomic_int * )dst , val );
260- }
261-
262- static inline void
263- mono_atomic_store_i64 (volatile gint64 * dst , gint64 val )
264- {
265- #if SIZEOF_LONG == 8
266- g_static_assert (sizeof (atomic_long ) == sizeof (* dst ) && ATOMIC_LONG_LOCK_FREE == 2 );
267- atomic_store ((volatile atomic_long * )dst , val );
268- #elif SIZEOF_LONG_LONG == 8
269- g_static_assert (sizeof (atomic_llong ) == sizeof (* dst ) && ATOMIC_LLONG_LOCK_FREE == 2 );
270- atomic_store ((volatile atomic_llong * )dst , val );
271- #else
272- #error gint64 not same size atomic_llong or atomic_long, don't define MONO_USE_STDATOMIC
273- #endif
274- }
275-
276- static inline void
277- mono_atomic_store_ptr (volatile gpointer * dst , gpointer val )
278- {
279- g_static_assert (ATOMIC_POINTER_LOCK_FREE == 2 );
280- atomic_store ((volatile _Atomic (gpointer ) * )dst , val );
281- }
282-
283- #elif defined(HOST_WIN32 )
28+ #if defined(HOST_WIN32 )
28429
28530#ifndef WIN32_LEAN_AND_MEAN
28631#define WIN32_LEAN_AND_MEAN
0 commit comments