diff --git a/intern/atomic/atomic_ops.h b/intern/atomic/atomic_ops.h index e6ca7a105ba..ad404c756ce 100644 --- a/intern/atomic/atomic_ops.h +++ b/intern/atomic/atomic_ops.h @@ -87,6 +87,9 @@ ATOMIC_INLINE int32_t atomic_fetch_and_add_int32(int32_t *p, int32_t x); ATOMIC_INLINE int32_t atomic_fetch_and_or_int32(int32_t *p, int32_t x); ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x); +ATOMIC_INLINE int16_t atomic_fetch_and_or_int16(int16_t *p, int16_t b); +ATOMIC_INLINE int16_t atomic_fetch_and_and_int16(int16_t *p, int16_t b); + ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b); ATOMIC_INLINE uint8_t atomic_fetch_and_and_uint8(uint8_t *p, uint8_t b); diff --git a/intern/atomic/intern/atomic_ops_msvc.h b/intern/atomic/intern/atomic_ops_msvc.h index 356140541ba..c9ad1a46ab9 100644 --- a/intern/atomic/intern/atomic_ops_msvc.h +++ b/intern/atomic/intern/atomic_ops_msvc.h @@ -162,6 +162,20 @@ ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x) return InterlockedAnd((long *)p, x); } +/******************************************************************************/ +/* 16-bit operations. */ + +/* Signed */ +ATOMIC_INLINE int16_t atomic_fetch_and_or_int16(int16_t *p, int16_t x) +{ + return InterlockedOr16((short *)p, x); +} + +ATOMIC_INLINE int16_t atomic_fetch_and_and_int16(int16_t *p, int16_t x) +{ + return InterlockedAnd16((short *)p, x); +} + /******************************************************************************/ /* 8-bit operations. */ diff --git a/intern/atomic/intern/atomic_ops_unix.h b/intern/atomic/intern/atomic_ops_unix.h index 0de9daaaf5f..dc1e71cda76 100644 --- a/intern/atomic/intern/atomic_ops_unix.h +++ b/intern/atomic/intern/atomic_ops_unix.h @@ -55,6 +55,7 @@ * its gcc doesn't have __GCC_HAVE_SYNC_COMPARE_AND_SWAP_n defined. */ # define JE_FORCE_SYNC_COMPARE_AND_SWAP_1 +# define JE_FORCE_SYNC_COMPARE_AND_SWAP_2 # define JE_FORCE_SYNC_COMPARE_AND_SWAP_4 # define JE_FORCE_SYNC_COMPARE_AND_SWAP_8 #endif @@ -325,6 +326,24 @@ ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x) # error "Missing implementation for 32-bit atomic operations" #endif +/******************************************************************************/ +/* 16-bit operations. */ +#if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_2)) + +/* Signed */ +ATOMIC_INLINE int16_t atomic_fetch_and_and_int16(int16_t *p, int16_t b) +{ + return __sync_fetch_and_and(p, b); +} +ATOMIC_INLINE int16_t atomic_fetch_and_or_int16(int16_t *p, int16_t b) +{ + return __sync_fetch_and_or(p, b); +} + +#else +# error "Missing implementation for 16-bit atomic operations" +#endif + /******************************************************************************/ /* 8-bit operations. */ #if (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) || defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_1)) diff --git a/intern/atomic/tests/atomic_test.cc b/intern/atomic/tests/atomic_test.cc index 6178b5074a7..661c130c65d 100644 --- a/intern/atomic/tests/atomic_test.cc +++ b/intern/atomic/tests/atomic_test.cc @@ -559,6 +559,39 @@ TEST(atomic, atomic_fetch_and_and_int32) /** \} */ +/** \name 16 bit signed int atomics + * \{ */ + +TEST(atomic, atomic_fetch_and_or_int16) +{ + { + int16_t value = 12; + EXPECT_EQ(atomic_fetch_and_or_int16(&value, 5), 12); + EXPECT_EQ(value, 13); + } + + { + int16_t value = 0x1234; + EXPECT_EQ(atomic_fetch_and_or_int16(&value, -0x5678), 0x1234); + EXPECT_EQ(value, -0x4444); + } +} + +TEST(atomic, atomic_fetch_and_and_int16) +{ + { + int16_t value = 12; + EXPECT_EQ(atomic_fetch_and_and_int16(&value, 5), 12); + EXPECT_EQ(value, 4); + } + + { + int16_t value = 0x1234; + EXPECT_EQ(atomic_fetch_and_and_int16(&value, -0x789A), 0x1234); + EXPECT_EQ(value, 0x224); + } +} + /** \name 8 bit unsigned int atomics * \{ */