From f66436cff70ad44abf3f576d5cc2034bfccfecf7 Mon Sep 17 00:00:00 2001 From: "digit@google.com" Date: Wed, 11 Jan 2012 17:44:41 +0000 Subject: [PATCH] android: optimize atomics routines This patch provides a slightly optimized implementation of atomic increment/decrement functions by using static inlined versions of the gcc intrinsics. Review URL: http://codereview.appspot.com/5498069 git-svn-id: http://skia.googlecode.com/svn/trunk@3012 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/core/SkThread_platform.h | 43 ++++++++++++++++++++++++++++++-- src/ports/SkThread_pthread.cpp | 4 +++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/include/core/SkThread_platform.h b/include/core/SkThread_platform.h index 2d94571061..d83f3eddb8 100644 --- a/include/core/SkThread_platform.h +++ b/include/core/SkThread_platform.h @@ -10,14 +10,53 @@ #ifndef SkThread_platform_DEFINED #define SkThread_platform_DEFINED -#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK) +#if defined(SK_BUILD_FOR_ANDROID) -#include +#if defined(SK_BUILD_FOR_ANDROID_NDK) + +#include + +/* Just use the GCC atomic intrinsics. They're supported by the NDK toolchain, + * have reasonable performance, and provide full memory barriers + */ +static __attribute__((always_inline)) int32_t sk_atomic_inc(int32_t *addr) { + return __sync_fetch_and_add(addr, 1); +} + +static __attribute__((always_inline)) int32_t sk_atomic_dec(int32_t *addr) { + return __sync_fetch_and_add(addr, -1); +} + +#else // !SK_BUILD_FOR_ANDROID_NDK + +/* The platform atomics operations are slightly more efficient than the + * GCC built-ins, so use them. + */ #include #define sk_atomic_inc(addr) android_atomic_inc(addr) #define sk_atomic_dec(addr) android_atomic_dec(addr) +#endif // !SK_BUILD_FOR_ANDROID_NDK + +#else // !SK_BUILD_FOR_ANDROID + +/** Implemented by the porting layer, this function adds 1 to the int specified + by the address (in a thread-safe manner), and returns the previous value. +*/ +SK_API int32_t sk_atomic_inc(int32_t* addr); +/** Implemented by the porting layer, this function subtracts 1 to the int + specified by the address (in a thread-safe manner), and returns the previous + value. +*/ +SK_API int32_t sk_atomic_dec(int32_t* addr); + +#endif // !SK_BUILD_FOR_ANDROID + +#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK) + +#include + class SkMutex : android::Mutex { public: // if isGlobal is true, then ignore any errors in the platform-specific diff --git a/src/ports/SkThread_pthread.cpp b/src/ports/SkThread_pthread.cpp index bab26e9928..51c0859031 100644 --- a/src/ports/SkThread_pthread.cpp +++ b/src/ports/SkThread_pthread.cpp @@ -10,6 +10,8 @@ #include #include +#ifndef SK_BUILD_FOR_ANDROID + /** We prefer the GCC intrinsic implementation of the atomic operations over the SkMutex-based implementation. The SkMutex version suffers from static @@ -61,6 +63,8 @@ int32_t sk_atomic_dec(int32_t* addr) #endif +#endif // SK_BUILD_FOR_ANDROID + ////////////////////////////////////////////////////////////////////////////// static void print_pthread_error(int status)