diff options
author | digit@google.com <digit@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-01-26 21:26:40 +0000 |
---|---|---|
committer | digit@google.com <digit@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-01-26 21:26:40 +0000 |
commit | 1771cbf43d9a1334e3d870c635b4215bb888dd98 (patch) | |
tree | b32203ccd81d3747e2cc36d5e71ee7cadcff03fa /include/core | |
parent | 72b55be3f3448287e8ff6fe83633edadfb60f59a (diff) |
posix: Avoid static initializers in static/global mutexes
This patch removes static initializers related to static and
global mutexes from the final library's machine code when
building on a pthread-capable system.
We use PTHREAD_MUTEX_INITIALIZER to perform POD-style
initialization. You need a line like the following to declare
a global mutex with it:
SkBaseMutex gMutex = { PTHREAD_MUTEX_INITIALIZER };
We introduce the SK_DECLARE_STATIC_MUTEX and SK_DECLARE_GLOBAL_MUTEX
macros to be able to declare static/global mutexes in the source tree
uniformly.
SkMutex is now defined as a sub-class of SkBaseMutex, with standard
construction/destruction semantics. This is useful if the mutex
object is a member of another C++ class, or allocated dynamically.
We also modify a few places to refer to SkBaseMutex instead of a
SkMutex, where it makes sense. Generally speaking, client code
should hold and use pointers to SkBaseMutex whenever they can
now.
We defined a new built-time macro named SK_USE_POSIX_THREADS
to indicate that we're using a pthread-based SkThread.h
interface. The macro will also be used in future patches
to implement other helper thread synchronization classes.
Finally, we inline the acquire() and release() functions in the
case of Posix to improve performance a bit.
Running: 'bench -repeat 10 -match mutex' on an Android device or
a 2.4GHz Xeon Linux desktop shows the following improvements:
Before After
Galaxy Nexus 1.64 1.45
Nexus S 1.47 1.16
Xoom 1.86 1.66
Xeon 0.36 0.31
This removes 5 static mutex initializers from the library
Review URL: https://codereview.appspot.com/5501066
git-svn-id: http://skia.googlecode.com/svn/trunk@3091 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/core')
-rw-r--r-- | include/core/SkPixelRef.h | 8 | ||||
-rw-r--r-- | include/core/SkThread.h | 4 | ||||
-rw-r--r-- | include/core/SkThread_platform.h | 47 |
3 files changed, 51 insertions, 8 deletions
diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h index e247479ad5..3f0784433e 100644 --- a/include/core/SkPixelRef.h +++ b/include/core/SkPixelRef.h @@ -52,7 +52,7 @@ class SkGpuTexture; */ class SkPixelRef : public SkRefCnt { public: - explicit SkPixelRef(SkMutex* mutex = NULL); + explicit SkPixelRef(SkBaseMutex* mutex = NULL); /** Return the pixel memory returned from lockPixels, or null if the lockCount is 0. @@ -201,16 +201,16 @@ protected: /** Return the mutex associated with this pixelref. This value is assigned in the constructor, and cannot change during the lifetime of the object. */ - SkMutex* mutex() const { return fMutex; } + SkBaseMutex* mutex() const { return fMutex; } - SkPixelRef(SkFlattenableReadBuffer&, SkMutex*); + SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); private: #if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS static void InitializeFlattenables(); #endif - SkMutex* fMutex; // must remain in scope for the life of this object + SkBaseMutex* fMutex; // must remain in scope for the life of this object void* fPixels; SkColorTable* fColorTable; // we do not track ownership, subclass does int fLockCount; diff --git a/include/core/SkThread.h b/include/core/SkThread.h index 5f2da4a006..1495a16fa9 100644 --- a/include/core/SkThread.h +++ b/include/core/SkThread.h @@ -31,7 +31,7 @@ public: class SkAutoMutexAcquire : SkNoncopyable { public: - explicit SkAutoMutexAcquire(SkMutex& mutex) : fMutex(&mutex) + explicit SkAutoMutexAcquire(SkBaseMutex& mutex) : fMutex(&mutex) { SkASSERT(fMutex != NULL); mutex.acquire(); @@ -55,7 +55,7 @@ public: } private: - SkMutex* fMutex; + SkBaseMutex* fMutex; }; #endif diff --git a/include/core/SkThread_platform.h b/include/core/SkThread_platform.h index cbb4891c1a..94a4a1edeb 100644 --- a/include/core/SkThread_platform.h +++ b/include/core/SkThread_platform.h @@ -78,7 +78,44 @@ SK_API int32_t sk_atomic_inc(int32_t* addr); */ SK_API int32_t sk_atomic_dec(int32_t* addr); -class SkMutex { +#endif + +#ifdef SK_USE_POSIX_THREADS + +#include <pthread.h> + +// A SkBaseMutex is a POD structure that can be directly initialized +// at declaration time with SK_DECLARE_STATIC/GLOBAL_MUTEX. This avoids the +// generation of a static initializer in the final machine code (and +// a corresponding static finalizer). +// +struct SkBaseMutex { + void acquire() { pthread_mutex_lock(&fMutex); } + void release() { pthread_mutex_unlock(&fMutex); } + pthread_mutex_t fMutex; +}; + +// Using POD-style initialization prevents the generation of a static initializer +// and keeps the acquire() implementation small and fast. +#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER } + +// Special case used when the static mutex must be available globally. +#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER } + +// A normal mutex that requires to be initialized through normal C++ construction, +// i.e. when it's a member of another class, or allocated on the heap. +class SkMutex : public SkBaseMutex, SkNoncopyable { +public: + SkMutex(); + ~SkMutex(); +}; + +#else // !SK_USE_POSIX_THREADS + +// In the generic case, SkBaseMutex and SkMutex are the same thing, and we +// can't easily get rid of static initializers. +// +class SkMutex : SkNoncopyable { public: SkMutex(); ~SkMutex(); @@ -94,6 +131,12 @@ private: uint32_t fStorage[kStorageIntCount]; }; -#endif +typedef SkMutex SkBaseMutex; + +#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name +#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name + +#endif // !SK_USE_POSIX_THREADS + #endif |