Use gcc intrinsic functions for atomic incr and decr
Review URL: http://codereview.appspot.com/4894055/
git-svn-id: http://skia.googlecode.com/svn/trunk@2138 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/ports/SkThread_pthread.cpp b/src/ports/SkThread_pthread.cpp
index 26f18a1..885a325 100644
--- a/src/ports/SkThread_pthread.cpp
+++ b/src/ports/SkThread_pthread.cpp
@@ -10,6 +10,35 @@
#include <pthread.h>
#include <errno.h>
+/**
+ We prefer the GCC intrinsic implementation of the atomic operations over the
+ SkMutex-based implementation. The SkMutex version suffers from static
+ destructor ordering problems.
+ Note clang also defines the GCC version macros and implements the intrinsics.
+ TODO: Verify that gcc-style __sync_* intrinsics work on ARM
+ According to this the intrinsics are supported on ARM in LLVM 2.7+
+ http://llvm.org/releases/2.7/docs/ReleaseNotes.html
+*/
+#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || __GNUC__ > 4
+ #if (defined(__x86_64) || defined(__i386__))
+ #define GCC_INTRINSIC
+ #endif
+#endif
+
+#if defined(GCC_INTRINSIC)
+
+int32_t sk_atomic_inc(int32_t* addr)
+{
+ return __sync_fetch_and_add(addr, 1);
+}
+
+int32_t sk_atomic_dec(int32_t* addr)
+{
+ return __sync_fetch_and_add(addr, -1);
+}
+
+#else
+
SkMutex gAtomicMutex;
int32_t sk_atomic_inc(int32_t* addr)
@@ -30,6 +59,8 @@
return value;
}
+#endif
+
//////////////////////////////////////////////////////////////////////////////
static void print_pthread_error(int status)