[asterisk-commits] trunk r16601 - in /trunk:
include/asterisk/lock.h utils.c
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu Mar 30 16:26:24 MST 2006
Author: rizzo
Date: Thu Mar 30 17:26:22 2006
New Revision: 16601
URL: http://svn.digium.com/view/asterisk?rev=16601&view=rev
Log:
initial implementation of support for native atomic ops.
Modified:
trunk/include/asterisk/lock.h
trunk/utils.c
Modified: trunk/include/asterisk/lock.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/lock.h?rev=16601&r1=16600&r2=16601&view=diff
==============================================================================
--- trunk/include/asterisk/lock.h (original)
+++ trunk/include/asterisk/lock.h Thu Mar 30 17:26:22 2006
@@ -679,4 +679,50 @@
#define pthread_create __use_ast_pthread_create_instead__
#endif
+/*
+ * Initial support for atomic instructions.
+ * For platforms that have it, use the native cpu instruction to
+ * implement them. For other platforms, resort to a 'slow' version
+ * (defined in utils.c) that protects the atomic instruction with
+ * a single lock.
+ * The slow versions is always available, for testing purposes,
+ * as ast_atomic_fetchadd_int_slow()
+ */
+
+int ast_atomic_fetchadd_int_slow(volatile int *p, int v);
+
+#include "asterisk/inline_api.h"
+
+/*! \brief Atomically add v to *pp and return * the previous value of *p.
+ * This can be used to handle reference counts, and the return value
+ * can be used to generate unique identifiers.
+ */
+
+#if defined ( __i386__)
+AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+ __asm __volatile (
+ " lock xaddl %0, %1 ; "
+ : "+r" (v), /* 0 (result) */
+ "=m" (*p) /* 1 */
+ : "m" (*p)); /* 2 */
+ return (v);
+})
+#else /* low performance version in utils.c */
+AST_INLINE_AP(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+ return ast_atomic_fetchadd_int_slow(p, v);
+})
+#endif
+
+/*! \brief decrement *p by 1 and return true if the variable has reached 0.
+ * Useful e.g. to check if a refcount has reached 0.
+ */
+AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
+{
+ int a = ast_atomic_fetchadd_int(p, -1);
+ return a == 1; /* true if the value is 0 now (so it was 1 previously) */
+}
+)
+
#endif /* _ASTERISK_LOCK_H */
Modified: trunk/utils.c
URL: http://svn.digium.com/view/asterisk/trunk/utils.c?rev=16601&r1=16600&r2=16601&view=diff
==============================================================================
--- trunk/utils.c (original)
+++ trunk/utils.c Thu Mar 30 17:26:22 2006
@@ -39,6 +39,7 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+#define AST_API_MODULE /* ensure that inlinable API functions will be built in lock.h if required */
#include "asterisk/lock.h"
#include "asterisk/io.h"
#include "asterisk/logger.h"
@@ -1049,6 +1050,16 @@
va_end(ap2);
}
+AST_MUTEX_DEFINE_STATIC(fetchadd_m); /* used for all fetc&add ops */
+int ast_atomic_fetchadd_int_slow(volatile int *p, int v)
+{
+ int ret;
+ ast_mutex_lock(&fetchadd_m);
+ ret = *p;
+ *p += v;
+ ast_mutex_unlock(&fetchadd_m);
+ return ret;
+}
/*! \brief
* get values from config variables.
More information about the asterisk-commits
mailing list