Add atomic swap and cmpxchg for void * as well.

Issue #232.
This commit is contained in:
Matt Pharr
2012-04-11 06:12:31 -07:00
parent 66765dc123
commit 491fa239bd
2 changed files with 107 additions and 1 deletions

View File

@@ -3797,6 +3797,13 @@ For global atomics, only atomic swap is available for these types:
float atomic_swap_global(uniform float * uniform ptr, float value) float atomic_swap_global(uniform float * uniform ptr, float value)
double atomic_swap_global(uniform double * uniform ptr, double value) double atomic_swap_global(uniform double * uniform ptr, double value)
Finally, "swap" (but none of these other atomics) is available for pointer
types:
::
void *atomic_swap_{local,global}(void * * uniform ptr, void * value)
There are also variants of the atomic that take ``uniform`` values for the There are also variants of the atomic that take ``uniform`` values for the
operand and return a ``uniform`` result. These correspond to a single operand and return a ``uniform`` result. These correspond to a single
atomic operation being performed for the entire gang of program instances, atomic operation being performed for the entire gang of program instances,
@@ -3821,6 +3828,13 @@ rather than one per program instance.
uniform int32 atomic_swap_{local,global}(uniform int32 * uniform ptr, uniform int32 atomic_swap_{local,global}(uniform int32 * uniform ptr,
uniform int32 newval) uniform int32 newval)
And similarly for pointers:
::
uniform void *atomic_swap_{local,global}(void * * uniform ptr,
void *newval)
Be careful that you use the atomic function that you mean to; consider the Be careful that you use the atomic function that you mean to; consider the
following code: following code:
@@ -3862,12 +3876,18 @@ the same location in memory!)
int32 atomic_xor_{local,global}(uniform int32 * varying ptr, int32 value) int32 atomic_xor_{local,global}(uniform int32 * varying ptr, int32 value)
int32 atomic_swap_{local,global}(uniform int32 * varying ptr, int32 value) int32 atomic_swap_{local,global}(uniform int32 * varying ptr, int32 value)
And:
::
void *atomic_swap_{local,global}(void * * ptr, void *value)
There are also atomic "compare and exchange" functions. Compare and There are also atomic "compare and exchange" functions. Compare and
exchange atomically compares the value in "val" to "compare"--if they exchange atomically compares the value in "val" to "compare"--if they
match, it assigns "newval" to "val". In either case, the old value of match, it assigns "newval" to "val". In either case, the old value of
"val" is returned. (As with the other atomic operations, there are also "val" is returned. (As with the other atomic operations, there are also
``unsigned`` and 64-bit variants of this function. Furthermore, there are ``unsigned`` and 64-bit variants of this function. Furthermore, there are
``float`` and ``double`` variants as well.) ``float``, ``double``, and ``void *`` variants as well.)
:: ::

View File

@@ -1772,6 +1772,49 @@ ATOMIC_DECL_CMPXCHG(double, double, IntMaskType)
#undef ATOMIC_DECL_CMPXCHG #undef ATOMIC_DECL_CMPXCHG
// void * variants of swap and compare exchange
static inline void *atomic_swap_global(void ** uniform ptr,
void * value) {
return (void *)atomic_swap_global((intptr_t * uniform)ptr,
(intptr_t)value);
}
static inline void * uniform atomic_swap_global(void ** uniform ptr,
void * uniform value) {
return (void * uniform)atomic_swap_global((intptr_t * uniform)ptr,
(uniform intptr_t)value);
}
static inline void *atomic_swap_global(void ** ptr, void * value) {
return (void *)atomic_swap_global((intptr_t *)ptr,
(intptr_t)value);
}
static inline void *
atomic_compare_exchange_global(void ** uniform ptr,
void * oldval, void * newval) {
return (void *)atomic_compare_exchange_global((intptr_t * uniform)ptr,
(intptr_t)oldval,
(intptr_t)newval);
}
static inline void * uniform
atomic_compare_exchange_global(void ** uniform ptr, void * uniform oldval,
void * uniform newval) {
return (void * uniform)atomic_compare_exchange_global((intptr_t * uniform)ptr,
(uniform intptr_t)oldval,
(uniform intptr_t)newval);
}
static inline void *
atomic_compare_exchange_global(void ** ptr, void * oldval,
void * newval) {
return (void *)atomic_compare_exchange_global((intptr_t *)ptr,
(intptr_t)oldval,
(intptr_t)newval);
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// local atomics // local atomics
@@ -1943,6 +1986,49 @@ LOCAL_CMPXCHG(double)
#undef LOCAL_ATOMIC #undef LOCAL_ATOMIC
#undef LOCAL_CMPXCHG #undef LOCAL_CMPXCHG
// void * variants of swap and compare exchange
static inline void *atomic_swap_local(void ** uniform ptr,
void * value) {
return (void *)atomic_swap_local((intptr_t * uniform)ptr,
(intptr_t)value);
}
static inline void * uniform atomic_swap_local(void ** uniform ptr,
void * uniform value) {
return (void * uniform)atomic_swap_local((intptr_t * uniform)ptr,
(uniform intptr_t)value);
}
static inline void *atomic_swap_local(void ** ptr, void * value) {
return (void *)atomic_swap_local((intptr_t *)ptr,
(intptr_t)value);
}
static inline void *
atomic_compare_exchange_local(void ** uniform ptr,
void * oldval, void * newval) {
return (void *)atomic_compare_exchange_local((intptr_t * uniform)ptr,
(intptr_t)oldval,
(intptr_t)newval);
}
static inline void * uniform
atomic_compare_exchange_local(void ** uniform ptr, void * uniform oldval,
void * uniform newval) {
return (void * uniform)atomic_compare_exchange_local((intptr_t * uniform)ptr,
(uniform intptr_t)oldval,
(uniform intptr_t)newval);
}
static inline void *
atomic_compare_exchange_local(void ** ptr, void * oldval,
void * newval) {
return (void *)atomic_compare_exchange_local((intptr_t *)ptr,
(intptr_t)oldval,
(intptr_t)newval);
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Transcendentals (float precision) // Transcendentals (float precision)