[tor-commits] [tor-browser] 09/81: Bug 1774458 - Use undocumented, non-public adaptive spinlocks on macOS 10.15+, revert to user-space spinlocks on older versions r=pbone
gitolite role
git at cupani.torproject.org
Tue Oct 18 16:12:03 UTC 2022
This is an automated email from the git hooks/post-receive script.
pierov pushed a commit to branch tor-browser-102.4.0esr-12.0-1
in repository tor-browser.
commit bf7fd007cfa41c09be385bfdb7ef65fa80a83ed5
Author: Gabriele Svelto <gsvelto at mozilla.com>
AuthorDate: Mon Jul 4 14:00:11 2022 +0000
Bug 1774458 - Use undocumented, non-public adaptive spinlocks on macOS 10.15+, revert to user-space spinlocks on older versions r=pbone
Differential Revision: https://phabricator.services.mozilla.com/D149599
---
memory/build/Mutex.cpp | 21 +++++++++++++++
memory/build/Mutex.h | 71 ++++++++++++++++++++++++++++++++++++++++++++------
memory/build/moz.build | 1 +
3 files changed, 85 insertions(+), 8 deletions(-)
diff --git a/memory/build/Mutex.cpp b/memory/build/Mutex.cpp
new file mode 100644
index 000000000000..5a7c6d46e99c
--- /dev/null
+++ b/memory/build/Mutex.cpp
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Mutex.h"
+
+#if defined(XP_DARWIN)
+
+// static
+bool Mutex::UseUnfairLocks() {
+ if (__builtin_available(macOS 10.15, *)) {
+ return true;
+ }
+
+ return false;
+}
+
+// static
+bool Mutex::gFallbackToOSSpinLock = !UseUnfairLocks();
+
+#endif // defined(XP_DARWIN)
diff --git a/memory/build/Mutex.h b/memory/build/Mutex.h
index 67fd1cc107f6..3827a8a6757f 100644
--- a/memory/build/Mutex.h
+++ b/memory/build/Mutex.h
@@ -10,21 +10,48 @@
#if defined(XP_WIN)
# include <windows.h>
#elif defined(XP_DARWIN)
+# include <libkern/OSAtomic.h>
# include <os/lock.h>
#else
# include <pthread.h>
#endif
#include "mozilla/Attributes.h"
+#if defined(XP_DARWIN)
+// For information about the following undocumented flags and functions see
+// https://github.com/apple/darwin-xnu/blob/main/bsd/sys/ulock.h and
+// https://github.com/apple/darwin-libplatform/blob/main/private/os/lock_private.h
+# define OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION (0x00010000)
+# define OS_UNFAIR_LOCK_ADAPTIVE_SPIN (0x00040000)
+
+extern "C" {
+
+typedef uint32_t os_unfair_lock_options_t;
+OS_UNFAIR_LOCK_AVAILABILITY
+OS_EXPORT OS_NOTHROW OS_NONNULL_ALL void os_unfair_lock_lock_with_options(
+ os_unfair_lock_t lock, os_unfair_lock_options_t options);
+}
+
+static_assert(OS_UNFAIR_LOCK_INIT._os_unfair_lock_opaque == OS_SPINLOCK_INIT,
+ "OS_UNFAIR_LOCK_INIT and OS_SPINLOCK_INIT have the same "
+ "value");
+static_assert(sizeof(os_unfair_lock) == sizeof(OSSpinLock),
+ "os_unfair_lock and OSSpinLock are the same size");
+#endif // defined(XP_DARWIN)
+
// Mutexes based on spinlocks. We can't use normal pthread spinlocks in all
-// places, because they require malloc()ed memory, which causes bootstrapping
-// issues in some cases. We also can't use constructors, because for statics,
-// they would fire after the first use of malloc, resetting the locks.
+// places, because they require malloc()ed memory, which causes
+// bootstrapping issues in some cases. We also can't use constructors,
+// because for statics, they would fire after the first use of malloc,
+// resetting the locks.
struct Mutex {
#if defined(XP_WIN)
CRITICAL_SECTION mMutex;
#elif defined(XP_DARWIN)
- os_unfair_lock mMutex;
+ union {
+ os_unfair_lock mUnfairLock;
+ OSSpinLock mSpinLock;
+ } mMutex;
#else
pthread_mutex_t mMutex;
#endif
@@ -36,7 +63,10 @@ struct Mutex {
return false;
}
#elif defined(XP_DARWIN)
- mMutex = OS_UNFAIR_LOCK_INIT;
+ // The hack below works because both OS_UNFAIR_LOCK_INIT and
+ // OS_SPINLOCK_INIT initialize the lock to 0 and in both case it's a 32-bit
+ // integer.
+ mMutex.mUnfairLock = OS_UNFAIR_LOCK_INIT;
#elif defined(XP_LINUX) && !defined(ANDROID)
pthread_mutexattr_t attr;
if (pthread_mutexattr_init(&attr) != 0) {
@@ -60,7 +90,20 @@ struct Mutex {
#if defined(XP_WIN)
EnterCriticalSection(&mMutex);
#elif defined(XP_DARWIN)
- os_unfair_lock_lock(&mMutex);
+ if (Mutex::gFallbackToOSSpinLock) {
+ OSSpinLockLock(&mMutex.mSpinLock);
+ } else {
+ // We rely on a non-public function to improve performance here.
+ // The OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION flag informs the kernel that
+ // the calling thread is able to make progress even in absence of actions
+ // from other threads and the OS_UNFAIR_LOCK_ADAPTIVE_SPIN one causes the
+ // kernel to spin on a contested lock if the owning thread is running on
+ // the same physical core (presumably only on x86 CPUs given that ARM
+ // macs don't have cores capable of SMT).
+ os_unfair_lock_lock_with_options(
+ &mMutex.mUnfairLock,
+ OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION | OS_UNFAIR_LOCK_ADAPTIVE_SPIN);
+ }
#else
pthread_mutex_lock(&mMutex);
#endif
@@ -70,11 +113,20 @@ struct Mutex {
#if defined(XP_WIN)
LeaveCriticalSection(&mMutex);
#elif defined(XP_DARWIN)
- os_unfair_lock_unlock(&mMutex);
+ if (Mutex::gFallbackToOSSpinLock) {
+ OSSpinLockUnlock(&mMutex.mSpinLock);
+ } else {
+ os_unfair_lock_unlock(&mMutex.mUnfairLock);
+ }
#else
pthread_mutex_unlock(&mMutex);
#endif
}
+
+#if defined(XP_DARWIN)
+ static bool UseUnfairLocks();
+ static bool gFallbackToOSSpinLock;
+#endif // XP_DARWIN
};
// Mutex that can be used for static initialization.
@@ -101,7 +153,10 @@ struct StaticMutex {
typedef Mutex StaticMutex;
# if defined(XP_DARWIN)
-# define STATIC_MUTEX_INIT OS_UNFAIR_LOCK_INIT
+// The hack below works because both OS_UNFAIR_LOCK_INIT and OS_SPINLOCK_INIT
+// initialize the lock to 0 and in both case it's a 32-bit integer.
+# define STATIC_MUTEX_INIT \
+ { .mUnfairLock = OS_UNFAIR_LOCK_INIT }
# elif defined(XP_LINUX) && !defined(ANDROID)
# define STATIC_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
# else
diff --git a/memory/build/moz.build b/memory/build/moz.build
index 85dc1f31aa83..70a2864585b9 100644
--- a/memory/build/moz.build
+++ b/memory/build/moz.build
@@ -37,6 +37,7 @@ if CONFIG["OS_TARGET"] == "Darwin" and (
CONFIG["MOZ_REPLACE_MALLOC"] or CONFIG["MOZ_MEMORY"]
):
SOURCES += [
+ "Mutex.cpp",
"zone.c",
]
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the tor-commits
mailing list