I’ve done a lot of research, looked over Bob’s excellent analysis, and
looked at some practical examples of lockless programming (scary stuff,
don’t do it!), and I think I’ve come up with an API that more closely
matches the use cases.
I’d love to get feedback on this proposal…
(All these functions are full memory barriers)
/* A struct so people don’t accidentally use normal operations on it */
typedef struct { int value; } SDL_atomic_t;
/* Set an atomic variable to a value, returning the previous value */
int SDL_AtomicSet(SDL_atomic_t *a, int value);
/* Get the value of an atomic variable */
int SDL_AtomicGet(SDL_atomic_t *a);
/* Add to an atomic variable, returning the previous value */
int SDL_AtomicAdd(SDL_atomic_t *a, int value);
/* Increment an atomic variable used as a reference count */
void SDL_AtomicIncRef(SDL_atomic_t *a);
/* Decrement an atomic variable used as a reference count,
returning SDL_TRUE if the variable has reached zero after decrementing
*/
SDL_bool SDL_AtomicDecRef(SDL_atomic_t *a);
/* Set an atomic variable to a new value if it is currently an old value,
returning SDL_TRUE if the value was set.
If you don’t know what this function is for, you shouldn’t use it!
*/
SDL_bool SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval);
/* Set a pointer to a new value if it is currently an old value,
returning SDL_TRUE if the value was set.
If you don’t know what this function is for, you shouldn’t use it!
*/
SDL_bool SDL_AtomicCASPtr(void **a, void *oldval, void *newval);–
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC