Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2020-12-04 18:25:49 +0300
committerJulian Eisel <julian@blender.org>2020-12-04 18:57:32 +0300
commit67b48290853a9d7e8f92764a6a3938c3a804c294 (patch)
tree2e2a855feec81f1528739ffebc5705093452dbc1
parentd07009498ac36d067fbccd61cfbcd51d4e2ba310 (diff)
Atomics: Add 16 bit fetch + AND and fetch + OR signed integer operationstemp-atomics-int16
I could use a 16 bit atomic fetch + AND for D9719. The alternative would be to turn a `short` into a `int` in DNA, which isn't a nice workaround. Also adds tests for the new functions.
-rw-r--r--intern/atomic/atomic_ops.h3
-rw-r--r--intern/atomic/intern/atomic_ops_msvc.h14
-rw-r--r--intern/atomic/intern/atomic_ops_unix.h19
-rw-r--r--intern/atomic/tests/atomic_test.cc33
4 files changed, 69 insertions, 0 deletions
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
@@ -163,6 +163,20 @@ ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t 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. */
/* Unsigned */
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
@@ -326,6 +327,24 @@ ATOMIC_INLINE int32_t atomic_fetch_and_and_int32(int32_t *p, int32_t x)
#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))
/* Unsigned */
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
* \{ */