Fixed bug 4683 - SDL_atomic infinite recursion on armv6/armv5 w/ thumb
authorSam Lantinga <slouken@libsdl.org>
Sun, 30 Jun 2019 23:26:16 -0700
changeset 1291212a6ba543f44
parent 12911 0c19a7239a95
child 12915 e8773976e7c6
Fixed bug 4683 - SDL_atomic infinite recursion on armv6/armv5 w/ thumb

The real problem is that SDL_atomic.c was built in thumb mode instead of ARM mode, which is required to use the mcr instruction on ARM platforms. Added a compiler error to catch this case so we don't generate code that does infinite recursion.

I also added a potentially better way to handle things on Linux ARM platforms, based on comments in the Chromium headers, which we can try out after 2.0.10 ships.
include/SDL_atomic.h
src/atomic/SDL_atomic.c
     1.1 --- a/include/SDL_atomic.h	Sun Jun 30 22:48:13 2019 -0700
     1.2 +++ b/include/SDL_atomic.h	Sun Jun 30 23:26:16 2019 -0700
     1.3 @@ -162,6 +162,22 @@
     1.4  #define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("dmb ish" : : : "memory")
     1.5  #define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("dmb ish" : : : "memory")
     1.6  #elif defined(__GNUC__) && defined(__arm__)
     1.7 +#if 0 /* defined(__LINUX__) || defined(__ANDROID__) */
     1.8 +/* Information from:
     1.9 +   https://chromium.googlesource.com/chromium/chromium/+/trunk/base/atomicops_internals_arm_gcc.h#19
    1.10 +
    1.11 +   The Linux kernel provides a helper function which provides the right code for a memory barrier,
    1.12 +   hard-coded at address 0xffff0fa0
    1.13 +*/
    1.14 +typedef void (*SDL_KernelMemoryBarrierFunc)();
    1.15 +#define SDL_MemoryBarrierRelease()	((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
    1.16 +#define SDL_MemoryBarrierAcquire()	((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
    1.17 +#elif 0 /* defined(__QNXNTO__) */
    1.18 +#include <sys/cpuinline.h>
    1.19 +
    1.20 +#define SDL_MemoryBarrierRelease()   __cpu_membarrier()
    1.21 +#define SDL_MemoryBarrierAcquire()   __cpu_membarrier()
    1.22 +#else
    1.23  #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__)
    1.24  #define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("dmb ish" : : : "memory")
    1.25  #define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("dmb ish" : : : "memory")
    1.26 @@ -177,6 +193,7 @@
    1.27  #else
    1.28  #define SDL_MemoryBarrierRelease()   __asm__ __volatile__ ("" : : : "memory")
    1.29  #define SDL_MemoryBarrierAcquire()   __asm__ __volatile__ ("" : : : "memory")
    1.30 +#endif /* __LINUX__ || __ANDROID__ */
    1.31  #endif /* __GNUC__ && __arm__ */
    1.32  #else
    1.33  #if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
     2.1 --- a/src/atomic/SDL_atomic.c	Sun Jun 30 22:48:13 2019 -0700
     2.2 +++ b/src/atomic/SDL_atomic.c	Sun Jun 30 23:26:16 2019 -0700
     2.3 @@ -289,6 +289,10 @@
     2.4  #endif
     2.5  }
     2.6  
     2.7 +#ifdef __thumb__
     2.8 +#error This file should be built in arm mode so the mcr instruction is available for memory barriers
     2.9 +#endif
    2.10 +
    2.11  void
    2.12  SDL_MemoryBarrierReleaseFunction(void)
    2.13  {