use atomic operations provided by the compiler if they are available (yay for gcc...
[asterisk/asterisk.git] / include / asterisk / lock.h
index db85c49..f60e04e 100644 (file)
@@ -738,12 +738,17 @@ 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.
+/*! \brief Atomically add v to *p 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__)
+#if defined(HAVE_GCC_ATOMICS)
+AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
+{
+       return __sync_fetch_and_add(p, v);
+})
+#elif defined ( __i386__)
 AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
 {
        __asm __volatile (
@@ -763,12 +768,18 @@ AST_INLINE_API(int ast_atomic_fetchadd_int(volatile int *p, int v),
 /*! \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.
  */
+#if defined(HAVE_GCC_ATOMICS)
+AST_INLINE_API(int ast_atomic_dec_and_test(volatile int *p),
+{
+       return __sync_sub_and_fetch(p, 1) == 0;
+})
+#else
 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
 
 #ifndef DEBUG_CHANNEL_LOCKS
 /*! \brief Lock a channel. If DEBUG_CHANNEL_LOCKS is defined