mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-17 15:21:43 +00:00

Most SDL functions used to indicate success or failure using an int return code. These functions have been changed to return SDL_bool. Here is a coccinelle patch to change code that previously compared the return value to 0 and changes it to a boolean test: @ bool_return_type @ identifier func =~ "^(SDL_AddEventWatch|SDL_AddHintCallback|SDL_AddSurfaceAlternateImage|SDL_AddVulkanRenderSemaphores|SDL_BindAudioStream|SDL_BindAudioStreams|SDL_BlitSurface|SDL_BlitSurface9Grid|SDL_BlitSurfaceScaled|SDL_BlitSurfaceTiled|SDL_BlitSurfaceTiledWithScale|SDL_BlitSurfaceUnchecked|SDL_BlitSurfaceUncheckedScaled|SDL_CaptureMouse|SDL_ClearAudioStream|SDL_ClearClipboardData|SDL_ClearComposition|SDL_ClearError|SDL_ClearProperty|SDL_ClearSurface|SDL_CloseIO|SDL_CloseStorage|SDL_ConvertAudioSamples|SDL_ConvertEventToRenderCoordinates|SDL_ConvertPixels|SDL_ConvertPixelsAndColorspace|SDL_CopyFile|SDL_CopyProperties|SDL_CopyStorageFile|SDL_CreateDirectory|SDL_CreateStorageDirectory|SDL_CreateWindowAndRenderer|SDL_DateTimeToTime|SDL_DestroyWindowSurface|SDL_DetachVirtualJoystick|SDL_DisableScreenSaver|SDL_EnableScreenSaver|SDL_EnumerateDirectory|SDL_EnumerateProperties|SDL_EnumerateStorageDirectory|SDL_FillSurfaceRect|SDL_FillSurfaceRects|SDL_FlashWindow|SDL_FlipSurface|SDL_FlushAudioStream|SDL_FlushRenderer|SDL_GL_DestroyContext|SDL_GL_GetAttribute|SDL_GL_GetSwapInterval|SDL_GL_LoadLibrary|SDL_GL_MakeCurrent|SDL_GL_SetAttribute|SDL_GL_SetSwapInterval|SDL_GL_SwapWindow|SDL_GetAudioDeviceFormat|SDL_GetAudioStreamFormat|SDL_GetCameraFormat|SDL_GetClosestFullscreenDisplayMode|SDL_GetCurrentRenderOutputSize|SDL_GetCurrentTime|SDL_GetDXGIOutputInfo|SDL_GetDateTimeLocalePreferences|SDL_GetDisplayBounds|SDL_GetDisplayUsableBounds|SDL_GetGDKDefaultUser|SDL_GetGDKTaskQueue|SDL_GetGamepadSensorData|SDL_GetGamepadTouchpadFinger|SDL_GetHapticEffectStatus|SDL_GetJoystickBall|SDL_GetMasksForPixelFormat|SDL_GetPathInfo|SDL_GetRectUnion|SDL_GetRectUnionFloat|SDL_GetRenderClipRect|SDL_GetRenderColorScale|SDL_GetRenderDrawBlendMode|SDL_GetRenderDrawColor|SDL_GetRenderDrawColorFloat|SDL_GetRenderLogicalPresentation|SDL_GetRenderLogicalPresentationRect|SDL_GetRenderOutputSize|SDL_GetRenderSafeArea|SDL_GetRenderScale|SDL_GetRenderVSync|SDL_GetRenderViewport|SDL_GetSensorData|SDL_GetStorageFileSize|SDL_GetStoragePathInfo|SDL_GetSurfaceAlphaMod|SDL_GetSurfaceBlendMode|SDL_GetSurfaceClipRect|SDL_GetSurfaceColorKey|SDL_GetSurfaceColorMod|SDL_GetTextInputArea|SDL_GetTextureAlphaMod|SDL_GetTextureAlphaModFloat|SDL_GetTextureBlendMode|SDL_GetTextureColorMod|SDL_GetTextureColorModFloat|SDL_GetTextureScaleMode|SDL_GetTextureSize|SDL_GetWindowAspectRatio|SDL_GetWindowBordersSize|SDL_GetWindowMaximumSize|SDL_GetWindowMinimumSize|SDL_GetWindowPosition|SDL_GetWindowRelativeMouseMode|SDL_GetWindowSafeArea|SDL_GetWindowSize|SDL_GetWindowSizeInPixels|SDL_GetWindowSurfaceVSync|SDL_HideCursor|SDL_HideWindow|SDL_Init|SDL_InitHapticRumble|SDL_InitSubSystem|SDL_LoadWAV|SDL_LoadWAV_IO|SDL_LockAudioStream|SDL_LockProperties|SDL_LockSurface|SDL_LockTexture|SDL_LockTextureToSurface|SDL_MaximizeWindow|SDL_MinimizeWindow|SDL_MixAudio|SDL_OpenURL|SDL_OutOfMemory|SDL_PauseAudioDevice|SDL_PauseAudioStreamDevice|SDL_PauseHaptic|SDL_PlayHapticRumble|SDL_PremultiplyAlpha|SDL_PremultiplySurfaceAlpha|SDL_PushEvent|SDL_PutAudioStreamData|SDL_RaiseWindow|SDL_ReadStorageFile|SDL_ReadSurfacePixel|SDL_ReadSurfacePixelFloat|SDL_RegisterApp|SDL_ReloadGamepadMappings|SDL_RemovePath|SDL_RemoveStoragePath|SDL_RemoveTimer|SDL_RenamePath|SDL_RenameStoragePath|SDL_RenderClear|SDL_RenderCoordinatesFromWindow|SDL_RenderCoordinatesToWindow|SDL_RenderFillRect|SDL_RenderFillRects|SDL_RenderGeometry|SDL_RenderGeometryRaw|SDL_RenderLine|SDL_RenderLines|SDL_RenderPoint|SDL_RenderPoints|SDL_RenderPresent|SDL_RenderRect|SDL_RenderRects|SDL_RenderTexture|SDL_RenderTexture9Grid|SDL_RenderTextureRotated|SDL_RenderTextureTiled|SDL_RequestAndroidPermission|SDL_RestoreWindow|SDL_ResumeAudioDevice|SDL_ResumeAudioStreamDevice|SDL_ResumeHaptic|SDL_RumbleGamepad|SDL_RumbleGamepadTriggers|SDL_RumbleJoystick|SDL_RumbleJoystickTriggers|SDL_RunHapticEffect|SDL_SaveBMP|SDL_SaveBMP_IO|SDL_SendAndroidMessage|SDL_SendGamepadEffect|SDL_SendJoystickEffect|SDL_SendJoystickVirtualSensorData|SDL_SetAppMetadata|SDL_SetAppMetadataProperty|SDL_SetAudioDeviceGain|SDL_SetAudioPostmixCallback|SDL_SetAudioStreamFormat|SDL_SetAudioStreamFrequencyRatio|SDL_SetAudioStreamGain|SDL_SetAudioStreamGetCallback|SDL_SetAudioStreamInputChannelMap|SDL_SetAudioStreamOutputChannelMap|SDL_SetAudioStreamPutCallback|SDL_SetBooleanProperty|SDL_SetClipboardData|SDL_SetClipboardText|SDL_SetCursor|SDL_SetFloatProperty|SDL_SetGamepadLED|SDL_SetGamepadMapping|SDL_SetGamepadPlayerIndex|SDL_SetGamepadSensorEnabled|SDL_SetHapticAutocenter|SDL_SetHapticGain|SDL_SetJoystickLED|SDL_SetJoystickPlayerIndex|SDL_SetJoystickVirtualAxis|SDL_SetJoystickVirtualBall|SDL_SetJoystickVirtualButton|SDL_SetJoystickVirtualHat|SDL_SetJoystickVirtualTouchpad|SDL_SetLinuxThreadPriority|SDL_SetLinuxThreadPriorityAndPolicy|SDL_SetLogPriorityPrefix|SDL_SetMemoryFunctions|SDL_SetNumberProperty|SDL_SetPaletteColors|SDL_SetPointerProperty|SDL_SetPointerPropertyWithCleanup|SDL_SetPrimarySelectionText|SDL_SetRenderClipRect|SDL_SetRenderColorScale|SDL_SetRenderDrawBlendMode|SDL_SetRenderDrawColor|SDL_SetRenderDrawColorFloat|SDL_SetRenderLogicalPresentation|SDL_SetRenderScale|SDL_SetRenderTarget|SDL_SetRenderVSync|SDL_SetRenderViewport|SDL_SetScancodeName|SDL_SetStringProperty|SDL_SetSurfaceAlphaMod|SDL_SetSurfaceBlendMode|SDL_SetSurfaceColorKey|SDL_SetSurfaceColorMod|SDL_SetSurfaceColorspace|SDL_SetSurfacePalette|SDL_SetSurfaceRLE|SDL_SetTLS|SDL_SetTextInputArea|SDL_SetTextureAlphaMod|SDL_SetTextureAlphaModFloat|SDL_SetTextureBlendMode|SDL_SetTextureColorMod|SDL_SetTextureColorModFloat|SDL_SetTextureScaleMode|SDL_SetThreadPriority|SDL_SetWindowAlwaysOnTop|SDL_SetWindowAspectRatio|SDL_SetWindowBordered|SDL_SetWindowFocusable|SDL_SetWindowFullscreen|SDL_SetWindowFullscreenMode|SDL_SetWindowHitTest|SDL_SetWindowIcon|SDL_SetWindowKeyboardGrab|SDL_SetWindowMaximumSize|SDL_SetWindowMinimumSize|SDL_SetWindowModalFor|SDL_SetWindowMouseGrab|SDL_SetWindowMouseRect|SDL_SetWindowOpacity|SDL_SetWindowPosition|SDL_SetWindowRelativeMouseMode|SDL_SetWindowResizable|SDL_SetWindowShape|SDL_SetWindowSize|SDL_SetWindowSurfaceVSync|SDL_SetWindowTitle|SDL_SetiOSAnimationCallback|SDL_ShowAndroidToast|SDL_ShowCursor|SDL_ShowMessageBox|SDL_ShowSimpleMessageBox|SDL_ShowWindow|SDL_ShowWindowSystemMenu|SDL_StartTextInput|SDL_StartTextInputWithProperties|SDL_StopHapticEffect|SDL_StopHapticEffects|SDL_StopHapticRumble|SDL_StopTextInput|SDL_SyncWindow|SDL_TimeToDateTime|SDL_TryLockMutex|SDL_TryLockRWLockForReading|SDL_TryLockRWLockForWriting|SDL_TryWaitSemaphore|SDL_UnlockAudioStream|SDL_UpdateHapticEffect|SDL_UpdateNVTexture|SDL_UpdateTexture|SDL_UpdateWindowSurface|SDL_UpdateWindowSurfaceRects|SDL_UpdateYUVTexture|SDL_Vulkan_CreateSurface|SDL_Vulkan_LoadLibrary|SDL_WaitConditionTimeout|SDL_WaitSemaphoreTimeout|SDL_WarpMouseGlobal|SDL_WriteStorageFile|SDL_WriteSurfacePixel|SDL_WriteSurfacePixelFloat)$"; @@ ( func( ... ) - == 0 | - func( + !func( ... ) - < 0 | - func( + !func( ... ) - != 0 | - func( + !func( ... ) - == -1 )
302 lines
9.6 KiB
C
302 lines
9.6 KiB
C
/*
|
|
Simple DirectMedia Layer
|
|
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
misrepresented as being the original software.
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
*/
|
|
#include "SDL_internal.h"
|
|
|
|
#if defined(_MSC_VER) && (_MSC_VER >= 1900)
|
|
#include <intrin.h>
|
|
#define HAVE_MSC_ATOMICS 1
|
|
#endif
|
|
|
|
#ifdef SDL_PLATFORM_MACOS // !!! FIXME: should we favor gcc atomics?
|
|
#include <libkern/OSAtomic.h>
|
|
#endif
|
|
|
|
#if !defined(HAVE_GCC_ATOMICS) && defined(SDL_PLATFORM_SOLARIS)
|
|
#include <atomic.h>
|
|
#endif
|
|
|
|
// The __atomic_load_n() intrinsic showed up in different times for different compilers.
|
|
#ifdef __clang__
|
|
#if __has_builtin(__atomic_load_n) || defined(HAVE_GCC_ATOMICS)
|
|
/* !!! FIXME: this advertises as available in the NDK but uses an external symbol we don't have.
|
|
It might be in a later NDK or we might need an extra library? --ryan. */
|
|
#ifndef SDL_PLATFORM_ANDROID
|
|
#define HAVE_ATOMIC_LOAD_N 1
|
|
#endif
|
|
#endif
|
|
#elif defined(__GNUC__)
|
|
#if (__GNUC__ >= 5)
|
|
#define HAVE_ATOMIC_LOAD_N 1
|
|
#endif
|
|
#endif
|
|
|
|
/* *INDENT-OFF* */ // clang-format off
|
|
#if defined(__WATCOMC__) && defined(__386__)
|
|
SDL_COMPILE_TIME_ASSERT(intsize, 4==sizeof(int));
|
|
#define HAVE_WATCOM_ATOMICS
|
|
extern __inline int _SDL_xchg_watcom(volatile int *a, int v);
|
|
#pragma aux _SDL_xchg_watcom = \
|
|
"lock xchg [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
value [eax] \
|
|
modify exact [eax];
|
|
|
|
extern __inline unsigned char _SDL_cmpxchg_watcom(volatile int *a, int newval, int oldval);
|
|
#pragma aux _SDL_cmpxchg_watcom = \
|
|
"lock cmpxchg [edx], ecx" \
|
|
"setz al" \
|
|
parm [edx] [ecx] [eax] \
|
|
value [al] \
|
|
modify exact [eax];
|
|
|
|
extern __inline int _SDL_xadd_watcom(volatile int *a, int v);
|
|
#pragma aux _SDL_xadd_watcom = \
|
|
"lock xadd [ecx], eax" \
|
|
parm [ecx] [eax] \
|
|
value [eax] \
|
|
modify exact [eax];
|
|
|
|
#endif // __WATCOMC__ && __386__
|
|
/* *INDENT-ON* */ // clang-format on
|
|
|
|
/*
|
|
If any of the operations are not provided then we must emulate some
|
|
of them. That means we need a nice implementation of spin locks
|
|
that avoids the "one big lock" problem. We use a vector of spin
|
|
locks and pick which one to use based on the address of the operand
|
|
of the function.
|
|
|
|
To generate the index of the lock we first shift by 3 bits to get
|
|
rid on the zero bits that result from 32 and 64 bit alignment of
|
|
data. We then mask off all but 5 bits and use those 5 bits as an
|
|
index into the table.
|
|
|
|
Picking the lock this way insures that accesses to the same data at
|
|
the same time will go to the same lock. OTOH, accesses to different
|
|
data have only a 1/32 chance of hitting the same lock. That should
|
|
pretty much eliminate the chances of several atomic operations on
|
|
different data from waiting on the same "big lock". If it isn't
|
|
then the table of locks can be expanded to a new size so long as
|
|
the new size is a power of two.
|
|
|
|
Contributed by Bob Pendleton, bob@pendleton.com
|
|
*/
|
|
|
|
#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(SDL_PLATFORM_MACOS) && !defined(SDL_PLATFORM_SOLARIS) && !defined(HAVE_WATCOM_ATOMICS)
|
|
#define EMULATE_CAS 1
|
|
#endif
|
|
|
|
#ifdef EMULATE_CAS
|
|
static SDL_SpinLock locks[32];
|
|
|
|
static SDL_INLINE void enterLock(void *a)
|
|
{
|
|
uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f);
|
|
|
|
SDL_LockSpinlock(&locks[index]);
|
|
}
|
|
|
|
static SDL_INLINE void leaveLock(void *a)
|
|
{
|
|
uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f);
|
|
|
|
SDL_UnlockSpinlock(&locks[index]);
|
|
}
|
|
#endif
|
|
|
|
SDL_bool SDL_AtomicCompareAndSwap(SDL_AtomicInt *a, int oldval, int newval)
|
|
{
|
|
#ifdef HAVE_MSC_ATOMICS
|
|
SDL_COMPILE_TIME_ASSERT(atomic_cas, sizeof(long) == sizeof(a->value));
|
|
return _InterlockedCompareExchange((long *)&a->value, (long)newval, (long)oldval) == (long)oldval;
|
|
#elif defined(HAVE_WATCOM_ATOMICS)
|
|
return _SDL_cmpxchg_watcom(&a->value, newval, oldval);
|
|
#elif defined(HAVE_GCC_ATOMICS)
|
|
return __sync_bool_compare_and_swap(&a->value, oldval, newval);
|
|
#elif defined(SDL_PLATFORM_MACOS) // this is deprecated in 10.12 sdk; favor gcc atomics.
|
|
return OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value);
|
|
#elif defined(SDL_PLATFORM_SOLARIS)
|
|
return ((int)atomic_cas_uint((volatile uint_t *)&a->value, (uint_t)oldval, (uint_t)newval) == oldval);
|
|
#elif defined(EMULATE_CAS)
|
|
bool result = false;
|
|
|
|
enterLock(a);
|
|
if (a->value == oldval) {
|
|
a->value = newval;
|
|
result = true;
|
|
}
|
|
leaveLock(a);
|
|
|
|
return result;
|
|
#else
|
|
#error Please define your platform.
|
|
#endif
|
|
}
|
|
|
|
SDL_bool SDL_AtomicCompareAndSwapPointer(void **a, void *oldval, void *newval)
|
|
{
|
|
#ifdef HAVE_MSC_ATOMICS
|
|
return _InterlockedCompareExchangePointer(a, newval, oldval) == oldval;
|
|
#elif defined(HAVE_WATCOM_ATOMICS)
|
|
return _SDL_cmpxchg_watcom((int *)a, (long)newval, (long)oldval);
|
|
#elif defined(HAVE_GCC_ATOMICS)
|
|
return __sync_bool_compare_and_swap(a, oldval, newval);
|
|
#elif defined(SDL_PLATFORM_MACOS) && defined(__LP64__) // this is deprecated in 10.12 sdk; favor gcc atomics.
|
|
return OSAtomicCompareAndSwap64Barrier((int64_t)oldval, (int64_t)newval, (int64_t *)a);
|
|
#elif defined(SDL_PLATFORM_MACOS) && !defined(__LP64__) // this is deprecated in 10.12 sdk; favor gcc atomics.
|
|
return OSAtomicCompareAndSwap32Barrier((int32_t)oldval, (int32_t)newval, (int32_t *)a);
|
|
#elif defined(SDL_PLATFORM_SOLARIS)
|
|
return (atomic_cas_ptr(a, oldval, newval) == oldval);
|
|
#elif defined(EMULATE_CAS)
|
|
bool result = false;
|
|
|
|
enterLock(a);
|
|
if (*a == oldval) {
|
|
*a = newval;
|
|
result = true;
|
|
}
|
|
leaveLock(a);
|
|
|
|
return result;
|
|
#else
|
|
#error Please define your platform.
|
|
#endif
|
|
}
|
|
|
|
int SDL_AtomicSet(SDL_AtomicInt *a, int v)
|
|
{
|
|
#ifdef HAVE_MSC_ATOMICS
|
|
SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value));
|
|
return _InterlockedExchange((long *)&a->value, v);
|
|
#elif defined(HAVE_WATCOM_ATOMICS)
|
|
return _SDL_xchg_watcom(&a->value, v);
|
|
#elif defined(HAVE_GCC_ATOMICS)
|
|
return __sync_lock_test_and_set(&a->value, v);
|
|
#elif defined(SDL_PLATFORM_SOLARIS)
|
|
return (int)atomic_swap_uint((volatile uint_t *)&a->value, v);
|
|
#else
|
|
int value;
|
|
do {
|
|
value = a->value;
|
|
} while (!SDL_AtomicCompareAndSwap(a, value, v));
|
|
return value;
|
|
#endif
|
|
}
|
|
|
|
void *SDL_AtomicSetPtr(void **a, void *v)
|
|
{
|
|
#ifdef HAVE_MSC_ATOMICS
|
|
return _InterlockedExchangePointer(a, v);
|
|
#elif defined(HAVE_WATCOM_ATOMICS)
|
|
return (void *)_SDL_xchg_watcom((int *)a, (long)v);
|
|
#elif defined(HAVE_GCC_ATOMICS)
|
|
return __sync_lock_test_and_set(a, v);
|
|
#elif defined(SDL_PLATFORM_SOLARIS)
|
|
return atomic_swap_ptr(a, v);
|
|
#else
|
|
void *value;
|
|
do {
|
|
value = *a;
|
|
} while (!SDL_AtomicCompareAndSwapPointer(a, value, v));
|
|
return value;
|
|
#endif
|
|
}
|
|
|
|
int SDL_AtomicAdd(SDL_AtomicInt *a, int v)
|
|
{
|
|
#ifdef HAVE_MSC_ATOMICS
|
|
SDL_COMPILE_TIME_ASSERT(atomic_add, sizeof(long) == sizeof(a->value));
|
|
return _InterlockedExchangeAdd((long *)&a->value, v);
|
|
#elif defined(HAVE_WATCOM_ATOMICS)
|
|
return _SDL_xadd_watcom(&a->value, v);
|
|
#elif defined(HAVE_GCC_ATOMICS)
|
|
return __sync_fetch_and_add(&a->value, v);
|
|
#elif defined(SDL_PLATFORM_SOLARIS)
|
|
int pv = a->value;
|
|
membar_consumer();
|
|
atomic_add_int((volatile uint_t *)&a->value, v);
|
|
return pv;
|
|
#else
|
|
int value;
|
|
do {
|
|
value = a->value;
|
|
} while (!SDL_AtomicCompareAndSwap(a, value, (value + v)));
|
|
return value;
|
|
#endif
|
|
}
|
|
|
|
int SDL_AtomicGet(SDL_AtomicInt *a)
|
|
{
|
|
#ifdef HAVE_ATOMIC_LOAD_N
|
|
return __atomic_load_n(&a->value, __ATOMIC_SEQ_CST);
|
|
#elif defined(HAVE_MSC_ATOMICS)
|
|
SDL_COMPILE_TIME_ASSERT(atomic_get, sizeof(long) == sizeof(a->value));
|
|
return _InterlockedOr((long *)&a->value, 0);
|
|
#elif defined(HAVE_WATCOM_ATOMICS)
|
|
return _SDL_xadd_watcom(&a->value, 0);
|
|
#elif defined(HAVE_GCC_ATOMICS)
|
|
return __sync_or_and_fetch(&a->value, 0);
|
|
#elif defined(SDL_PLATFORM_MACOS) // this is deprecated in 10.12 sdk; favor gcc atomics.
|
|
return sizeof(a->value) == sizeof(uint32_t) ? OSAtomicOr32Barrier(0, (volatile uint32_t *)&a->value) : OSAtomicAdd64Barrier(0, (volatile int64_t *)&a->value);
|
|
#elif defined(SDL_PLATFORM_SOLARIS)
|
|
return atomic_or_uint_nv((volatile uint_t *)&a->value, 0);
|
|
#else
|
|
int value;
|
|
do {
|
|
value = a->value;
|
|
} while (!SDL_AtomicCompareAndSwap(a, value, value));
|
|
return value;
|
|
#endif
|
|
}
|
|
|
|
void *SDL_AtomicGetPtr(void **a)
|
|
{
|
|
#ifdef HAVE_ATOMIC_LOAD_N
|
|
return __atomic_load_n(a, __ATOMIC_SEQ_CST);
|
|
#elif defined(HAVE_MSC_ATOMICS)
|
|
return _InterlockedCompareExchangePointer(a, NULL, NULL);
|
|
#elif defined(HAVE_GCC_ATOMICS)
|
|
return __sync_val_compare_and_swap(a, (void *)0, (void *)0);
|
|
#elif defined(SDL_PLATFORM_SOLARIS)
|
|
return atomic_cas_ptr(a, (void *)0, (void *)0);
|
|
#else
|
|
void *value;
|
|
do {
|
|
value = *a;
|
|
} while (!SDL_AtomicCompareAndSwapPointer(a, value, value));
|
|
return value;
|
|
#endif
|
|
}
|
|
|
|
#ifdef SDL_MEMORY_BARRIER_USES_FUNCTION
|
|
#error This file should be built in arm mode so the mcr instruction is available for memory barriers
|
|
#endif
|
|
|
|
void SDL_MemoryBarrierReleaseFunction(void)
|
|
{
|
|
SDL_MemoryBarrierRelease();
|
|
}
|
|
|
|
void SDL_MemoryBarrierAcquireFunction(void)
|
|
{
|
|
SDL_MemoryBarrierAcquire();
|
|
}
|