Bug 1353787 - use first-fit mutexes on OS X; r=erahm
☠☠ backed out by 5ca1b0650836 ☠ ☠
authorNathan Froyd <froydnj@mozilla.com>
Fri, 07 Apr 2017 15:42:19 -0400
changeset 351974 e824f50f5ca648fda532a3d7ee4ba1093121aa4b
parent 351973 c1a6b2a6a71c01813a27cd03e5117a9829069d4b
child 351975 256f7bc3bf9a767029ef7747a35952a6bccad8a9
push id31624
push userarchaeopteryx@coole-files.de
push dateSat, 08 Apr 2017 20:49:20 +0000
treeherdermozilla-central@2a3ecdb7d1ea [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerserahm
bugs1353787
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1353787 - use first-fit mutexes on OS X; r=erahm Changing the fairness policy makes OS X mutexes roughly an order of magnitude faster in the contended case.
mozglue/misc/Mutex_posix.cpp
--- a/mozglue/misc/Mutex_posix.cpp
+++ b/mozglue/misc/Mutex_posix.cpp
@@ -18,50 +18,65 @@
     int result = (call);                        \
     if (result != 0) {                          \
       errno = result;                           \
       perror(msg);                              \
       MOZ_CRASH(msg);                           \
     }                                           \
   }
 
-mozilla::detail::MutexImpl::MutexImpl()
-{
-  pthread_mutexattr_t* attrp = nullptr;
-
-  // Linux with glibc and FreeBSD support adaptive mutexes that spin
-  // for a short number of tries before sleeping.  NSPR's locks did
-  // this, too, and it seems like a reasonable thing to do.
+// Linux with glibc and FreeBSD support adaptive mutexes that spin
+// for a short number of tries before sleeping.  NSPR's locks did
+// this, too, and it seems like a reasonable thing to do.
 #if (defined(__linux__) && defined(__GLIBC__)) || defined(__FreeBSD__)
 #define ADAPTIVE_MUTEX_SUPPORTED
 #endif
 
 #if defined(DEBUG)
-#define ATTR_REQUIRED
-#define MUTEX_KIND PTHREAD_MUTEX_ERRORCHECK
+#define ATTR_SETTYPE PTHREAD_MUTEX_ERRORCHECK
 #elif defined(ADAPTIVE_MUTEX_SUPPORTED)
-#define ATTR_REQUIRED
-#define MUTEX_KIND PTHREAD_MUTEX_ADAPTIVE_NP
+#define ATTR_SETTYPE PTHREAD_MUTEX_ADAPTIVE_NP
 #endif
 
-#if defined(ATTR_REQUIRED)
+#if defined(XP_DARWIN)
+// OS X's mutexes are fair by default, which means they can be rather
+// slow in the contended case.  OS X 10.7 and above provides an OS
+// X-only function to set the mutex fairness policy, which makes mutexes
+// non-fair (i.e. like every other platform we support) and increases
+// performance in the contended case by an order of magnitude or so.
+#include <pthread_spis.h>
+#define ATTR_SETPOLICY _PTHREAD_MUTEX_POLICY_FIRSTFIT
+#endif
+
+mozilla::detail::MutexImpl::MutexImpl()
+{
+  pthread_mutexattr_t* attrp = nullptr;
+
+#if defined(ATTR_SETTYPE) || defined(ATTR_SETPOLICY)
   pthread_mutexattr_t attr;
 
   TRY_CALL_PTHREADS(pthread_mutexattr_init(&attr),
                     "mozilla::detail::MutexImpl::MutexImpl: pthread_mutexattr_init failed");
 
-  TRY_CALL_PTHREADS(pthread_mutexattr_settype(&attr, MUTEX_KIND),
+#if defined(ATTR_SETTYPE)
+  TRY_CALL_PTHREADS(pthread_mutexattr_settype(&attr, ATTR_SETTYPE),
                     "mozilla::detail::MutexImpl::MutexImpl: pthread_mutexattr_settype failed");
+#endif
+#if defined(ATTR_SETPOLICY)
+  TRY_CALL_PTHREADS(pthread_mutexattr_setpolicy_np(&attr, ATTR_SETPOLICY),
+                    "mozilla::detail::MutexImpl::MutexImpl: pthread_mutex_setpolicy_np failed");
+#endif
+
   attrp = &attr;
 #endif
 
   TRY_CALL_PTHREADS(pthread_mutex_init(&platformData()->ptMutex, attrp),
                     "mozilla::detail::MutexImpl::MutexImpl: pthread_mutex_init failed");
 
-#if defined(ATTR_REQUIRED)
+#if defined(ATTR_SETTYPE) || defined(ATTR_SETPOLICY)
   TRY_CALL_PTHREADS(pthread_mutexattr_destroy(&attr),
                     "mozilla::detail::MutexImpl::MutexImpl: pthread_mutexattr_destroy failed");
 #endif
 }
 
 mozilla::detail::MutexImpl::~MutexImpl()
 {
   TRY_CALL_PTHREADS(pthread_mutex_destroy(&platformData()->ptMutex),