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
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index a58cd37..caca577 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -88,7 +88,7 @@
 
 struct SkFaceRec;
 
-static SkMutex      gFTMutex;
+SK_DECLARE_STATIC_MUTEX(gFTMutex);
 static int          gFTCount;
 static FT_Library   gFTLibrary;
 static SkFaceRec*   gFaceRecHead;
diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp
index 37c922c..a3bd79c 100644
--- a/src/ports/SkFontHost_android.cpp
+++ b/src/ports/SkFontHost_android.cpp
@@ -67,7 +67,7 @@
 static int32_t gUniqueFontID;
 
 // this is the mutex that protects these globals
-static SkMutex gFamilyMutex;
+SK_DECLARE_STATIC_MUTEX(gFamilyMutex);
 static FamilyRec* gFamilyHead;
 static SkTDArray<NameFamilyPair> gNameList;
 
diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp
index acc5ae0..454ded3 100644
--- a/src/ports/SkFontHost_fontconfig.cpp
+++ b/src/ports/SkFontHost_fontconfig.cpp
@@ -38,7 +38,7 @@
 // Although truetype fonts can support multiple faces in a single file, at the
 // moment Skia doesn't.
 // -----------------------------------------------------------------------------
-static SkMutex global_fc_map_lock;
+SK_DECLARE_STATIC_MUTEX(global_fc_map_lock);
 static std::map<std::string, unsigned> global_fc_map;
 static std::map<unsigned, std::string> global_fc_map_inverted;
 static std::map<uint32_t, SkTypeface *> global_fc_typefaces;
diff --git a/src/ports/SkFontHost_linux.cpp b/src/ports/SkFontHost_linux.cpp
index c87b036..fa1d2ec 100644
--- a/src/ports/SkFontHost_linux.cpp
+++ b/src/ports/SkFontHost_linux.cpp
@@ -60,7 +60,7 @@
 static int32_t gUniqueFontID;
 
 // this is the mutex that protects these globals
-static SkMutex gFamilyMutex;
+SK_DECLARE_STATIC_MUTEX(gFamilyMutex);
 static FamilyRec* gFamilyHead;
 static SkTDArray<NameFamilyPair> gNameList;
 
diff --git a/src/ports/SkFontHost_mac_atsui.cpp b/src/ports/SkFontHost_mac_atsui.cpp
index b90757c..ae32036 100644
--- a/src/ports/SkFontHost_mac_atsui.cpp
+++ b/src/ports/SkFontHost_mac_atsui.cpp
@@ -16,7 +16,7 @@
 #include "SkPoint.h"
 
 const char* gDefaultfont = "Arial"; // hard code for now
-static SkMutex      gFTMutex;
+SK_DECLARE_STATIC_MUTEX(gFTMutex);
 
 static inline SkPoint F32PtToSkPoint(const Float32Point p) {
     SkPoint sp = { SkFloatToScalar(p.x), SkFloatToScalar(p.y) };
diff --git a/src/ports/SkFontHost_mac_coretext.cpp b/src/ports/SkFontHost_mac_coretext.cpp
index 3ba11a8..9c69ed7 100644
--- a/src/ports/SkFontHost_mac_coretext.cpp
+++ b/src/ports/SkFontHost_mac_coretext.cpp
@@ -450,7 +450,7 @@
 }
 
 static SkTypeface* GetDefaultFace() {
-    static SkMutex gMutex;
+    SK_DECLARE_STATIC_MUTEX(gMutex);
     SkAutoMutexAcquire ma(gMutex);
 
     static SkTypeface* gDefaultFace;
diff --git a/src/ports/SkFontHost_simple.cpp b/src/ports/SkFontHost_simple.cpp
index 0624d35..7a06b10 100644
--- a/src/ports/SkFontHost_simple.cpp
+++ b/src/ports/SkFontHost_simple.cpp
@@ -59,7 +59,7 @@
 static int32_t gUniqueFontID;
 
 // this is the mutex that protects these globals
-static SkMutex gFamilyMutex;
+SK_DECLARE_STATIC_MUTEX(gFamilyMutex);
 static FamilyRec* gFamilyHead;
 static SkTDArray<NameFamilyPair> gNameList;
 
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 156f51c..e78bfbb 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -448,7 +448,7 @@
     return SkFixedToFIXED(SkFloatToFixed(x));
 }
 
-static SkMutex gFTMutex;
+SK_DECLARE_STATIC_MUTEX(gFTMutex);
 
 #define HIRES_TEXTSIZE  2048
 #define HIRES_SHIFT     11
diff --git a/src/ports/SkThread_pthread.cpp b/src/ports/SkThread_pthread.cpp
index 638e522..4750d4f 100644
--- a/src/ports/SkThread_pthread.cpp
+++ b/src/ports/SkThread_pthread.cpp
@@ -55,7 +55,7 @@
 int32_t sk_atomic_dec(int32_t* addr)
 {
     SkAutoMutexAcquire ac(gAtomicMutex);
-    
+
     int32_t value = *addr;
     *addr = value - 1;
     return value;
@@ -83,6 +83,30 @@
     }
 }
 
+#ifdef SK_USE_POSIX_THREADS
+
+SkMutex::SkMutex() {
+    int status;
+
+    status = pthread_mutex_init(&fMutex, NULL);
+    if (status != 0) {
+        print_pthread_error(status);
+        SkASSERT(0 == status);
+    }
+}
+
+SkMutex::~SkMutex() {
+    int status = pthread_mutex_destroy(&fMutex);
+
+    // only report errors on non-global mutexes
+    if (status != 0) {
+        print_pthread_error(status);
+        SkASSERT(0 == status);
+    }
+}
+
+#else // !SK_USE_POSIX_THREADS
+
 SkMutex::SkMutex() {
     if (sizeof(pthread_mutex_t) > sizeof(fStorage)) {
         SkDEBUGF(("pthread mutex size = %d\n", sizeof(pthread_mutex_t)));
@@ -124,3 +148,4 @@
     SkASSERT(0 == status);
 }
 
+#endif // !SK_USE_POSIX_THREADS