diff --git a/src/ddsrt/include/dds/ddsrt/atomics/arm.h b/src/ddsrt/include/dds/ddsrt/atomics/arm.h index 863e483..fd43723 100644 --- a/src/ddsrt/include/dds/ddsrt/atomics/arm.h +++ b/src/ddsrt/include/dds/ddsrt/atomics/arm.h @@ -85,6 +85,9 @@ inline void *ddsrt_atomic_addvoidp_nv (volatile ddsrt_atomic_voidp_t *x, ptrdiff inline void ddsrt_atomic_add32 (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { (void) ddsrt_atomic_add32_nv (x, v); } +inline uint32_t ddsrt_atomic_add32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { + return ddsrt_atomic_add32_nv (x, v) - v; +} inline void ddsrt_atomic_addptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v) { (void) ddsrt_atomic_addptr_nv (x, v); } @@ -115,6 +118,9 @@ inline void ddsrt_atomic_subvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v /* INC */ +inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) { + return ddsrt_atomic_add32_nv (x, 1) - 1; +} inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x) { return ddsrt_atomic_add32_nv (x, 1); } @@ -130,6 +136,9 @@ inline void ddsrt_atomic_incptr (volatile ddsrt_atomic_uintptr_t *x) { /* DEC */ +inline uint32_t ddsrt_atomic_dec32_ov (volatile ddsrt_atomic_uint32_t *x) { + return ddsrt_atomic_sub32_nv (x, 1) + 1; +} inline uint32_t ddsrt_atomic_dec32_nv (volatile ddsrt_atomic_uint32_t *x) { return ddsrt_atomic_sub32_nv (x, 1); } diff --git a/src/ddsrt/include/dds/ddsrt/atomics/gcc.h b/src/ddsrt/include/dds/ddsrt/atomics/gcc.h index 59e05a7..a005da2 100644 --- a/src/ddsrt/include/dds/ddsrt/atomics/gcc.h +++ b/src/ddsrt/include/dds/ddsrt/atomics/gcc.h @@ -85,6 +85,9 @@ inline void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x) { inline void ddsrt_atomic_incptr (volatile ddsrt_atomic_uintptr_t *x) { __sync_fetch_and_add (&x->v, 1); } +inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) { + return __sync_fetch_and_add (&x->v, 1); +} inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x) { return __sync_add_and_fetch (&x->v, 1); } @@ -149,6 +152,9 @@ inline void ddsrt_atomic_addptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v inline void ddsrt_atomic_addvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) { ddsrt_atomic_addptr ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v); } +inline uint32_t ddsrt_atomic_add32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { + return __sync_fetch_and_add (&x->v, v); +} inline uint32_t ddsrt_atomic_add32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { return __sync_add_and_fetch (&x->v, v); } @@ -180,6 +186,9 @@ inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v inline void ddsrt_atomic_subvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) { ddsrt_atomic_subptr ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v); } +inline uint32_t ddsrt_atomic_sub32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { + return __sync_fetch_and_sub (&x->v, v); +} inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { return __sync_sub_and_fetch (&x->v, v); } diff --git a/src/ddsrt/include/dds/ddsrt/atomics/msvc.h b/src/ddsrt/include/dds/ddsrt/atomics/msvc.h index f7f2218..c30f5f0 100644 --- a/src/ddsrt/include/dds/ddsrt/atomics/msvc.h +++ b/src/ddsrt/include/dds/ddsrt/atomics/msvc.h @@ -74,6 +74,9 @@ inline void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x) { inline void ddsrt_atomic_incptr (volatile ddsrt_atomic_uintptr_t *x) { DDSRT_ATOMIC_PTROP (InterlockedIncrement) (&x->v); } +inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) { + return InterlockedIncrement (&x->v) - 1; +} inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x) { return InterlockedIncrement (&x->v); } @@ -138,6 +141,9 @@ inline void ddsrt_atomic_addptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v inline void ddsrt_atomic_addvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) { ddsrt_atomic_addptr ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v); } +inline uint32_t ddsrt_atomic_add32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { + return InterlockedExchangeAdd (&x->v, v); +} inline uint32_t ddsrt_atomic_add32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { return InterlockedExchangeAdd (&x->v, v) + v; } @@ -178,6 +184,12 @@ inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v inline void ddsrt_atomic_subvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) { ddsrt_atomic_subptr ((volatile ddsrt_atomic_uintptr_t *) x, (uintptr_t) v); } +inline uint32_t ddsrt_atomic_sub32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { + /* disable unary minus applied to unsigned type, result still unsigned */ + DDSRT_WARNING_MSVC_OFF(4146) + return InterlockedExchangeAdd (&x->v, -v); + DDSRT_WARNING_MSVC_ON(4146) +} inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { /* disable unary minus applied to unsigned type, result still unsigned */ DDSRT_WARNING_MSVC_OFF(4146) diff --git a/src/ddsrt/include/dds/ddsrt/atomics/sun.h b/src/ddsrt/include/dds/ddsrt/atomics/sun.h index 74a7469..f9f1434 100644 --- a/src/ddsrt/include/dds/ddsrt/atomics/sun.h +++ b/src/ddsrt/include/dds/ddsrt/atomics/sun.h @@ -40,6 +40,11 @@ inline void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x) { inline void ddsrt_atomic_incptr (volatile ddsrt_atomic_uintptr_t *x) { atomic_inc_ulong (&x->v); } +inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x) { + uint32_t oldval, newval; + do { oldval = x->v; newval = oldval + 1; } while (atomic_cas_32 (&x->v, oldval, newval) != oldval); + return oldval; +} inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x) { return atomic_inc_32_nv (&x->v); } @@ -100,6 +105,9 @@ inline void ddsrt_atomic_addptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v inline void ddsrt_atomic_addvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) { atomic_add_ptr (&x->v, v); } +inline uint32_t ddsrt_atomic_add32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { + return atomic_add_32_nv (&x->v, v) - v; +} inline uint32_t ddsrt_atomic_add32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { return atomic_add_32_nv (&x->v, v); } @@ -127,6 +135,9 @@ inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v inline void ddsrt_atomic_subvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v) { atomic_add_ptr (&x->v, -v); } +inline uint32_t ddsrt_atomic_sub32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { + return atomic_add_32_nv (&x->v, -v) + v; +} inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v) { return atomic_add_32_nv (&x->v, -v); } diff --git a/src/ddsrt/src/atomics.c b/src/ddsrt/src/atomics.c index 5919a40..a23113c 100644 --- a/src/ddsrt/src/atomics.c +++ b/src/ddsrt/src/atomics.c @@ -30,6 +30,7 @@ extern inline void ddsrt_atomic_inc32 (volatile ddsrt_atomic_uint32_t *x); extern inline void ddsrt_atomic_inc64 (volatile ddsrt_atomic_uint64_t *x); #endif extern inline void ddsrt_atomic_incptr (volatile ddsrt_atomic_uintptr_t *x); +extern inline uint32_t ddsrt_atomic_inc32_ov (volatile ddsrt_atomic_uint32_t *x); extern inline uint32_t ddsrt_atomic_inc32_nv (volatile ddsrt_atomic_uint32_t *x); #if DDSRT_HAVE_ATOMIC64 extern inline uint64_t ddsrt_atomic_inc64_nv (volatile ddsrt_atomic_uint64_t *x); @@ -58,6 +59,7 @@ extern inline void ddsrt_atomic_add64 (volatile ddsrt_atomic_uint64_t *x, uint64 #endif extern inline void ddsrt_atomic_addptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v); extern inline void ddsrt_atomic_addvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v); +extern inline uint32_t ddsrt_atomic_add32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v); extern inline uint32_t ddsrt_atomic_add32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v); #if DDSRT_HAVE_ATOMIC64 extern inline uint64_t ddsrt_atomic_add64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v); @@ -71,6 +73,7 @@ extern inline void ddsrt_atomic_sub64 (volatile ddsrt_atomic_uint64_t *x, uint64 #endif extern inline void ddsrt_atomic_subptr (volatile ddsrt_atomic_uintptr_t *x, uintptr_t v); extern inline void ddsrt_atomic_subvoidp (volatile ddsrt_atomic_voidp_t *x, ptrdiff_t v); +extern inline uint32_t ddsrt_atomic_sub32_ov (volatile ddsrt_atomic_uint32_t *x, uint32_t v); extern inline uint32_t ddsrt_atomic_sub32_nv (volatile ddsrt_atomic_uint32_t *x, uint32_t v); #if DDSRT_HAVE_ATOMIC64 extern inline uint64_t ddsrt_atomic_sub64_nv (volatile ddsrt_atomic_uint64_t *x, uint64_t v);