Sfoglia il codice sorgente

Added SDL_AddAtomicU32()

Fixes https://github.com/libsdl-org/SDL/issues/13496
Sam Lantinga 2 settimane fa
parent
commit
42f634ff7a

+ 18 - 0
include/SDL3/SDL_atomic.h

@@ -596,6 +596,24 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v);
  */
 extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetAtomicU32(SDL_AtomicU32 *a);
 
+/**
+ * Add to an atomic variable.
+ *
+ * This function also acts as a full memory barrier.
+ *
+ * ***Note: If you don't know what this function is for, you shouldn't use
+ * it!***
+ *
+ * \param a a pointer to an SDL_AtomicU32 variable to be modified.
+ * \param v the desired value to add or subtract.
+ * \returns the previous value of the atomic variable.
+ *
+ * \threadsafety It is safe to call this function from any thread.
+ *
+ * \since This function is available since SDL 3.2.0.
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_AddAtomicU32(SDL_AtomicU32 *a, int v);
+
 /**
  * Set a pointer to a new value if it is currently an old value.
  *

+ 24 - 0
src/atomic/SDL_atomic.c

@@ -298,6 +298,30 @@ int SDL_AddAtomicInt(SDL_AtomicInt *a, int v)
 #endif
 }
 
+Uint32 SDL_AddAtomicU32(SDL_AtomicU32 *a, int v)
+{
+#ifdef HAVE_MSC_ATOMICS
+    SDL_COMPILE_TIME_ASSERT(atomic_add, sizeof(long) == sizeof(a->value));
+    return (Uint32)_InterlockedExchangeAdd((long *)&a->value, v);
+#elif defined(HAVE_WATCOM_ATOMICS)
+    SDL_COMPILE_TIME_ASSERT(atomic_add, sizeof(int) == sizeof(a->value));
+    return (Uint32)_SDL_xadd_watcom((volatile int *)&a->value, v);
+#elif defined(HAVE_GCC_ATOMICS)
+    return __sync_fetch_and_add(&a->value, v);
+#elif defined(SDL_PLATFORM_SOLARIS)
+    Uint32 pv = a->value;
+    membar_consumer();
+    atomic_add_int((volatile uint_t *)&a->value, v);
+    return pv;
+#else
+    Uint32 value;
+    do {
+        value = a->value;
+    } while (!SDL_CompareAndSwapAtomicU32(a, value, (value + v)));
+    return value;
+#endif
+}
+
 int SDL_GetAtomicInt(SDL_AtomicInt *a)
 {
 #ifdef HAVE_ATOMIC_LOAD_N

+ 1 - 0
src/dynapi/SDL_dynapi.sym

@@ -1253,6 +1253,7 @@ SDL3_0.0.0 {
     SDL_PutAudioStreamPlanarData;
     SDL_GetEventDescription;
     SDL_PutAudioStreamDataNoCopy;
+    SDL_AddAtomicU32;
     # extra symbols go here (don't modify this line)
   local: *;
 };

+ 1 - 0
src/dynapi/SDL_dynapi_overrides.h

@@ -1278,3 +1278,4 @@
 #define SDL_PutAudioStreamPlanarData SDL_PutAudioStreamPlanarData_REAL
 #define SDL_GetEventDescription SDL_GetEventDescription_REAL
 #define SDL_PutAudioStreamDataNoCopy SDL_PutAudioStreamDataNoCopy_REAL
+#define SDL_AddAtomicU32 SDL_AddAtomicU32_REAL

+ 1 - 0
src/dynapi/SDL_dynapi_procs.h

@@ -1286,3 +1286,4 @@ SDL_DYNAPI_PROC(SDL_Renderer*,SDL_CreateGPURenderer,(SDL_Window *a,SDL_GPUShader
 SDL_DYNAPI_PROC(bool,SDL_PutAudioStreamPlanarData,(SDL_AudioStream *a,const void * const*b,int c,int d),(a,b,c,d),return)
 SDL_DYNAPI_PROC(int,SDL_GetEventDescription,(const SDL_Event *a,char *b,int c),(a,b,c),return)
 SDL_DYNAPI_PROC(bool,SDL_PutAudioStreamDataNoCopy,(SDL_AudioStream *a,const void *b,int c,SDL_AudioStreamDataCompleteCallback d,void *e),(a,b,c,d,e),return)
+SDL_DYNAPI_PROC(Uint32,SDL_AddAtomicU32,(SDL_AtomicU32 *a,int b),(a,b),return)