summaryrefslogtreecommitdiff
path: root/ports/SkMutex_pthread.h
diff options
context:
space:
mode:
authorbungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-12-18 15:27:39 +0000
committerbungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-12-18 15:27:39 +0000
commit0c8d113f1a7092e0e659df48863c5f34df8718fa (patch)
treeb6b109db2606f5a590c9e2a50dbd16d89060c846 /ports/SkMutex_pthread.h
parentd953c0af5ade95862c027b7eb4b60657248962bd (diff)
downloadsrc-0c8d113f1a7092e0e659df48863c5f34df8718fa.tar.gz
Split atomic and mutex implementations and make inlinable.
Skia cannot use Chromium's implementation of mutex (Lock) due to static initializers. However, we would like to be able to use Chromium's implementation of atomics. This motivates the split of implementation. Skia's atomic and mutex calls should be inlinable, especially the atomics. These calls often compile down to very few instructions, and we currently have the overhead of a function call. This motivates the header implementation. There is still a desire for the build system to select the implementation, so the SK_XXX_PLATFORM_H pattern for header files is introduced. This allows the build system to control which platform specific header files are chosen. The Chromium side changes (most of which will need to go in before this change can be found at https://codereview.chromium.org/19477005/ . The Chromium side changes after this lands can be seen at https://codereview.chromium.org/98073013 . Review URL: https://codereview.chromium.org/19808007 git-svn-id: http://skia.googlecode.com/svn/trunk/src@12738 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'ports/SkMutex_pthread.h')
-rw-r--r--ports/SkMutex_pthread.h87
1 files changed, 87 insertions, 0 deletions
diff --git a/ports/SkMutex_pthread.h b/ports/SkMutex_pthread.h
new file mode 100644
index 00000000..d9f1ae30
--- /dev/null
+++ b/ports/SkMutex_pthread.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkMutex_pthread_DEFINED
+#define SkMutex_pthread_DEFINED
+
+/** Posix pthread_mutex based mutex. */
+
+#ifdef SK_DEBUG_PTHREAD_MUTEX
+#include "SkTypes.h"
+#define SkDEBUGCODE_PTHREAD_MUTEX(code) code
+#else
+#define SkDEBUGCODE_PTHREAD_MUTEX(code)
+#ifndef SkDebugf
+ void SkDebugf(const char format[], ...);
+#endif
+#endif
+
+#include <errno.h>
+#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;
+};
+
+// 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 {
+public:
+ SkMutex() {
+ SkDEBUGCODE_PTHREAD_MUTEX(int status = )pthread_mutex_init(&fMutex, NULL);
+ SkDEBUGCODE_PTHREAD_MUTEX(
+ if (status != 0) {
+ print_pthread_error(status);
+ SkASSERT(0 == status);
+ }
+ )
+ }
+
+ ~SkMutex() {
+ SkDEBUGCODE_PTHREAD_MUTEX(int status = )pthread_mutex_destroy(&fMutex);
+ SkDEBUGCODE_PTHREAD_MUTEX(
+ if (status != 0) {
+ print_pthread_error(status);
+ SkASSERT(0 == status);
+ }
+ )
+ }
+
+private:
+ SkMutex(const SkMutex&);
+ SkMutex& operator=(const SkMutex&);
+
+ static void print_pthread_error(int status) {
+ switch (status) {
+ case 0: // success
+ break;
+ case EINVAL:
+ SkDebugf("pthread error [%d] EINVAL\n", status);
+ break;
+ case EBUSY:
+ SkDebugf("pthread error [%d] EBUSY\n", status);
+ break;
+ default:
+ SkDebugf("pthread error [%d] unknown\n", status);
+ break;
+ }
+ }
+};
+
+// Using POD-style initialization prevents the generation of a static initializer.
+#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 }
+
+#endif