1
1
/*
2
2
Simple DirectMedia Layer
3
- Copyright (C) 1997-2016 Sam Lantinga <[email protected] >
3
+ Copyright (C) 1997-2019 Sam Lantinga <[email protected] >
4
4
5
5
This software is provided 'as-is', without any express or implied
6
6
warranty. In no event will the authors be held liable for any damages
56
56
* All of the atomic operations that modify memory are full memory barriers.
57
57
*/
58
58
59
- #ifndef _SDL_atomic_h_
60
- #define _SDL_atomic_h_
59
+ #ifndef SDL_atomic_h_
60
+ #define SDL_atomic_h_
61
61
62
62
#include "SDL_stdinc.h"
63
63
#include "SDL_platform.h"
@@ -118,13 +118,16 @@ extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock);
118
118
* The compiler barrier prevents the compiler from reordering
119
119
* reads and writes to globally visible variables across the call.
120
120
*/
121
- #if defined(_MSC_VER ) && (_MSC_VER > 1200 )
121
+ #if defined(_MSC_VER ) && (_MSC_VER > 1200 ) && !defined( __clang__ )
122
122
void _ReadWriteBarrier (void );
123
123
#pragma intrinsic(_ReadWriteBarrier)
124
124
#define SDL_CompilerBarrier () _ReadWriteBarrier()
125
125
#elif (defined(__GNUC__ ) && !defined(__EMSCRIPTEN__ )) || (defined(__SUNPRO_C ) && (__SUNPRO_C >= 0x5120 ))
126
126
/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */
127
127
#define SDL_CompilerBarrier () __asm__ __volatile__ ("" : : : "memory")
128
+ #elif defined(__WATCOMC__ )
129
+ extern _inline void SDL_CompilerBarrier (void );
130
+ #pragma aux SDL_CompilerBarrier = "" parm [] modify exact [];
128
131
#else
129
132
#define SDL_CompilerBarrier () \
130
133
{ SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); }
@@ -149,25 +152,49 @@ void _ReadWriteBarrier(void);
149
152
* For more information on these semantics, take a look at the blog post:
150
153
* http://preshing.com/20120913/acquire-and-release-semantics
151
154
*/
155
+ extern DECLSPEC void SDLCALL SDL_MemoryBarrierReleaseFunction (void );
156
+ extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction (void );
157
+
152
158
#if defined(__GNUC__ ) && (defined(__powerpc__ ) || defined(__ppc__ ))
153
159
#define SDL_MemoryBarrierRelease () __asm__ __volatile__ ("lwsync" : : : "memory")
154
160
#define SDL_MemoryBarrierAcquire () __asm__ __volatile__ ("lwsync" : : : "memory")
161
+ #elif defined(__GNUC__ ) && defined(__aarch64__ )
162
+ #define SDL_MemoryBarrierRelease () __asm__ __volatile__ ("dmb ish" : : : "memory")
163
+ #define SDL_MemoryBarrierAcquire () __asm__ __volatile__ ("dmb ish" : : : "memory")
155
164
#elif defined(__GNUC__ ) && defined(__arm__ )
156
- #if defined(__ARM_ARCH_7__ ) || defined(__ARM_ARCH_7A__ ) || defined(__ARM_ARCH_7EM__ ) || defined(__ARM_ARCH_7R__ ) || defined(__ARM_ARCH_7M__ ) || defined(__ARM_ARCH_7S__ )
165
+ #if 0 /* defined(__LINUX__) || defined(__ANDROID__) */
166
+ /* Information from:
167
+ https://chromium.googlesource.com/chromium/chromium/+/trunk/base/atomicops_internals_arm_gcc.h#19
168
+
169
+ The Linux kernel provides a helper function which provides the right code for a memory barrier,
170
+ hard-coded at address 0xffff0fa0
171
+ */
172
+ typedef void (* SDL_KernelMemoryBarrierFunc )();
173
+ #define SDL_MemoryBarrierRelease () ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
174
+ #define SDL_MemoryBarrierAcquire () ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
175
+ #elif 0 /* defined(__QNXNTO__) */
176
+ #include <sys/cpuinline.h>
177
+
178
+ #define SDL_MemoryBarrierRelease () __cpu_membarrier()
179
+ #define SDL_MemoryBarrierAcquire () __cpu_membarrier()
180
+ #else
181
+ #if defined(__ARM_ARCH_7__ ) || defined(__ARM_ARCH_7A__ ) || defined(__ARM_ARCH_7EM__ ) || defined(__ARM_ARCH_7R__ ) || defined(__ARM_ARCH_7M__ ) || defined(__ARM_ARCH_7S__ ) || defined(__ARM_ARCH_8A__ )
157
182
#define SDL_MemoryBarrierRelease () __asm__ __volatile__ ("dmb ish" : : : "memory")
158
183
#define SDL_MemoryBarrierAcquire () __asm__ __volatile__ ("dmb ish" : : : "memory")
159
- #elif defined(__ARM_ARCH_6__ ) || defined(__ARM_ARCH_6J__ ) || defined(__ARM_ARCH_6K__ ) || defined(__ARM_ARCH_6T2__ ) || defined(__ARM_ARCH_6Z__ ) || defined(__ARM_ARCH_6ZK__ )
184
+ #elif defined(__ARM_ARCH_6__ ) || defined(__ARM_ARCH_6J__ ) || defined(__ARM_ARCH_6K__ ) || defined(__ARM_ARCH_6T2__ ) || defined(__ARM_ARCH_6Z__ ) || defined(__ARM_ARCH_6ZK__ ) || defined( __ARM_ARCH_5TE__ )
160
185
#ifdef __thumb__
161
186
/* The mcr instruction isn't available in thumb mode, use real functions */
162
- extern DECLSPEC void SDLCALL SDL_MemoryBarrierRelease ();
163
- extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquire ();
187
+ #define SDL_MEMORY_BARRIER_USES_FUNCTION
188
+ #define SDL_MemoryBarrierRelease () SDL_MemoryBarrierReleaseFunction()
189
+ #define SDL_MemoryBarrierAcquire () SDL_MemoryBarrierAcquireFunction()
164
190
#else
165
191
#define SDL_MemoryBarrierRelease () __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
166
192
#define SDL_MemoryBarrierAcquire () __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
167
193
#endif /* __thumb__ */
168
194
#else
169
195
#define SDL_MemoryBarrierRelease () __asm__ __volatile__ ("" : : : "memory")
170
196
#define SDL_MemoryBarrierAcquire () __asm__ __volatile__ ("" : : : "memory")
197
+ #endif /* __LINUX__ || __ANDROID__ */
171
198
#endif /* __GNUC__ && __arm__ */
172
199
#else
173
200
#if (defined(__SUNPRO_C ) && (__SUNPRO_C >= 0x5120 ))
@@ -263,6 +290,6 @@ extern DECLSPEC void* SDLCALL SDL_AtomicGetPtr(void **a);
263
290
264
291
#include "close_code.h"
265
292
266
- #endif /* _SDL_atomic_h_ */
293
+ #endif /* SDL_atomic_h_ */
267
294
268
295
/* vi: set ts=4 sw=4 expandtab: */
0 commit comments