[Asterisk-code-review] core: Create ast atomic macro's. (asterisk[master])

Jenkins2 asteriskteam at digium.com
Wed Jan 31 17:06:57 CST 2018


Jenkins2 has submitted this change and it was merged. ( https://gerrit.asterisk.org/8107 )

Change subject: core: Create ast_atomic macro's.
......................................................................

core: Create ast_atomic macro's.

Create ast_atomic macro's to provide a consistent interface to the
common functionality of __atomic and __sync built-in functions.

ASTERISK-27619

Change-Id: Ieba3f81832a0e25c5725ea067e5d6f742d33eb5b
---
M include/asterisk/lock.h
1 file changed, 96 insertions(+), 5 deletions(-)

Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved
  Jenkins2: Approved for Submit



diff --git a/include/asterisk/lock.h b/include/asterisk/lock.h
index c3dd691..a46d047 100644
--- a/include/asterisk/lock.h
+++ b/include/asterisk/lock.h
@@ -617,19 +617,108 @@
 #define pthread_create __use_ast_pthread_create_instead__
 #endif
 
-/* Support for atomic instructions. */
+/*!
+ * \brief Support for atomic instructions.
+ *
+ * These macros implement a uniform interface to use built-in atomic functionality.
+ * If available __atomic built-ins are prefered.  Legacy __sync built-ins are used
+ * as a fallback for older compilers.
+ *
+ * Detailed documentation can be found in the GCC manual, all API's are modeled after
+ * the __atomic interfaces but using the namespace ast_atomic.
+ *
+ * The memorder argument is always ignored by legacy __sync functions.  Invalid
+ * memorder arguments do not produce errors unless __atomic functions are supported
+ * as the argument is erased by the preprocessor.
+ *
+ * \note ast_atomic_fetch_nand and ast_atomic_nand_fetch purposely do not exist.
+ *       It's implementation was broken prior to gcc-4.4.
+ *
+ * @{
+ */
 
 #include "asterisk/inline_api.h"
 
 #if defined(HAVE_C_ATOMICS)
-#define ast_atomic_fetch_add(p, v, memorder)  __atomic_fetch_add(p, v, memorder)
-#define ast_atomic_sub_fetch(p, v, memorder)  __atomic_sub_fetch(p, v, memorder)
+/*! Atomic += */
+#define ast_atomic_fetch_add(ptr, val, memorder)  __atomic_fetch_add((ptr), (val), (memorder))
+#define ast_atomic_add_fetch(ptr, val, memorder)  __atomic_add_fetch((ptr), (val), (memorder))
+
+/*! Atomic -= */
+#define ast_atomic_fetch_sub(ptr, val, memorder)  __atomic_fetch_sub((ptr), (val), (memorder))
+#define ast_atomic_sub_fetch(ptr, val, memorder)  __atomic_sub_fetch((ptr), (val), (memorder))
+
+/*! Atomic &= */
+#define ast_atomic_fetch_and(ptr, val, memorder)  __atomic_fetch_and((ptr), (val), (memorder))
+#define ast_atomic_and_fetch(ptr, val, memorder)  __atomic_and_fetch((ptr), (val), (memorder))
+
+/*! Atomic |= */
+#define ast_atomic_fetch_or(ptr, val, memorder)   __atomic_fetch_or((ptr), (val), (memorder))
+#define ast_atomic_or_fetch(ptr, val, memorder)   __atomic_or_fetch((ptr), (val), (memorder))
+
+/*! Atomic xor = */
+#define ast_atomic_fetch_xor(ptr, val, memorder)  __atomic_fetch_xor((ptr), (val), (memorder))
+#define ast_atomic_xor_fetch(ptr, val, memorder)  __atomic_xor_fetch((ptr), (val), (memorder))
+
+#if 0
+/* Atomic compare and swap
+ *
+ * See comments near the __atomic implementation for why this is disabled.
+ */
+#define ast_atomic_compare_exchange_n(ptr, expected, desired, success_memorder, failure_memorder) \
+	__atomic_compare_exchange_n((ptr), (expected), (desired), 0, success_memorder, failure_memorder)
+
+#define ast_atomic_compare_exchange(ptr, expected, desired, success_memorder, failure_memorder) \
+	__atomic_compare_exchange((ptr), (expected), (desired), 0, success_memorder, failure_memorder)
+#endif
+
 #elif defined(HAVE_GCC_ATOMICS)
-#define ast_atomic_fetch_add(p, v, memorder)  __sync_fetch_and_add(p, v)
-#define ast_atomic_sub_fetch(p, v, memorder)  __sync_sub_and_fetch(p, v)
+/*! Atomic += */
+#define ast_atomic_fetch_add(ptr, val, memorder)  __sync_fetch_and_add((ptr), (val))
+#define ast_atomic_add_fetch(ptr, val, memorder)  __sync_add_and_fetch((ptr), (val))
+
+/*! Atomic -= */
+#define ast_atomic_fetch_sub(ptr, val, memorder)  __sync_fetch_and_sub((ptr), (val))
+#define ast_atomic_sub_fetch(ptr, val, memorder)  __sync_sub_and_fetch((ptr), (val))
+
+/*! Atomic &= */
+#define ast_atomic_fetch_and(ptr, val, memorder)  __sync_fetch_and_and((ptr), (val))
+#define ast_atomic_and_fetch(ptr, val, memorder)  __sync_and_and_fetch((ptr), (val))
+
+/*! Atomic |= */
+#define ast_atomic_fetch_or(ptr, val, memorder)  __sync_fetch_and_or((ptr), (val))
+#define ast_atomic_or_fetch(ptr, val, memorder)  __sync_or_and_fetch((ptr), (val))
+
+/*! Atomic xor = */
+#define ast_atomic_fetch_xor(ptr, val, memorder)  __sync_fetch_and_xor((ptr), (val))
+#define ast_atomic_xor_fetch(ptr, val, memorder)  __sync_xor_and_fetch((ptr), (val))
+
+#if 0
+/* Atomic compare and swap
+ *
+ * The \a expected argument is a pointer, I'm guessing __atomic built-ins
+ * perform all memory reads/writes in a single atomic operation.  I don't
+ * believe this is possible to exactly replicate using __sync built-ins.
+ * Will need to determine potential use cases of this feature and write a
+ * wrapper which provides consistant behavior between __sync and __atomic
+ * implementations.
+ */
+#define ast_atomic_compare_exchange_n(ptr, expected, desired, success_memorder, failure_memorder) \
+	__sync_bool_compare_and_swap((ptr), *(expected), (desired))
+
+#define ast_atomic_compare_exchange(ptr, expected, desired, success_memorder, failure_memorder) \
+	__sync_bool_compare_and_swap((ptr), *(expected), *(desired))
+#endif
+
 #else
 #error "Atomics not available."
 #endif
+
+/*! Atomic flag set */
+#define ast_atomic_flag_set(ptr, val, memorder)   ast_atomic_fetch_or((ptr), (val), (memorder))
+
+/*! Atomic flag clear */
+#define ast_atomic_flag_clear(ptr, val, memorder) ast_atomic_fetch_and((ptr), ~(val), (memorder))
 
 /*!
  * \brief Atomically add v to *p and return the previous value of *p.
@@ -652,4 +741,6 @@
 	return ast_atomic_sub_fetch(p, 1, __ATOMIC_RELAXED) == 0;
 })
 
+/*! @} */
+
 #endif /* _ASTERISK_LOCK_H */

-- 
To view, visit https://gerrit.asterisk.org/8107
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Ieba3f81832a0e25c5725ea067e5d6f742d33eb5b
Gerrit-Change-Number: 8107
Gerrit-PatchSet: 1
Gerrit-Owner: Corey Farrell <git at cfware.com>
Gerrit-Reviewer: Jenkins2
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20180131/c5613470/attachment-0001.html>


More information about the asterisk-code-review mailing list