Commit 5e7fc52e authored by Nico Weber's avatar Nico Weber Committed by Commit Bot

linux, android: Always assume futex syscall is availabble.

Bug: 897742
Change-Id: Id980269ea623f9800b62aead3896d107690a64eb
Reviewed-on: https://chromium-review.googlesource.com/c/1293559Reviewed-by: default avatarPrimiano Tucci <primiano@chromium.org>
Commit-Queue: Nico Weber <thakis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601583}
parent 2102b285
...@@ -115,3 +115,4 @@ Modifications: ...@@ -115,3 +115,4 @@ Modifications:
- Pulled SuggestedDelayNS() implementation for 32bit architectures which do not support 64bit atomicity - Pulled SuggestedDelayNS() implementation for 32bit architectures which do not support 64bit atomicity
- Pulled several mipsel related changes from lss project to fix compile errors - Pulled several mipsel related changes from lss project to fix compile errors
- Fixed line endings in vendor/README_windows.txt to Unix (LF) - Fixed line endings in vendor/README_windows.txt to Unix (LF)
- Removed have_futex from spinlock_linux-inl.h; assume it's always there
...@@ -53,27 +53,6 @@ ...@@ -53,27 +53,6 @@
// which prefers direct system calls in order to improve compatibility // which prefers direct system calls in order to improve compatibility
// with older toolchains and runtime libraries. // with older toolchains and runtime libraries.
static bool have_futex;
static int futex_private_flag = FUTEX_PRIVATE_FLAG;
namespace {
static struct InitModule {
InitModule() {
int x = 0;
// futexes are ints, so we can use them only when
// that's the same size as the lockword_ in SpinLock.
have_futex = (sizeof(Atomic32) == sizeof(int) &&
syscall(__NR_futex, &x, FUTEX_WAKE, 1, NULL, NULL, 0) >= 0);
if (have_futex && syscall(__NR_futex, &x, FUTEX_WAKE | futex_private_flag,
1, NULL, NULL, 0) < 0) {
futex_private_flag = 0;
}
}
} init_module;
} // anonymous namespace
namespace base { namespace base {
namespace internal { namespace internal {
...@@ -82,28 +61,18 @@ void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) { ...@@ -82,28 +61,18 @@ void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
int save_errno = errno; int save_errno = errno;
struct timespec tm; struct timespec tm;
tm.tv_sec = 0; tm.tv_sec = 0;
if (have_futex) { tm.tv_nsec = base::internal::SuggestedDelayNS(loop);
tm.tv_nsec = base::internal::SuggestedDelayNS(loop); tm.tv_nsec *= 16; // increase the delay; we expect explicit wakeups
} else { syscall(__NR_futex, reinterpret_cast<int*>(const_cast<Atomic32*>(w)),
tm.tv_nsec = 2000001; // above 2ms so linux 2.4 doesn't spin FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value,
} reinterpret_cast<struct kernel_timespec*>(&tm), NULL, 0);
if (have_futex) {
tm.tv_nsec *= 16; // increase the delay; we expect explicit wakeups
syscall(__NR_futex, reinterpret_cast<int*>(const_cast<Atomic32*>(w)),
FUTEX_WAIT | futex_private_flag, value,
reinterpret_cast<struct kernel_timespec*>(&tm), NULL, 0);
} else {
nanosleep(&tm, NULL);
}
errno = save_errno; errno = save_errno;
} }
} }
void SpinLockWake(volatile Atomic32 *w, bool all) { void SpinLockWake(volatile Atomic32 *w, bool all) {
if (have_futex) { syscall(__NR_futex, reinterpret_cast<int*>(const_cast<Atomic32*>(w)),
syscall(__NR_futex, reinterpret_cast<int*>(const_cast<Atomic32*>(w)), FUTEX_WAKE | FUTEX_PRIVATE_FLAG, all ? INT_MAX : 1, NULL, NULL, 0);
FUTEX_WAKE | futex_private_flag, all ? INT_MAX : 1, NULL, NULL, 0);
}
} }
} // namespace internal } // namespace internal
......
...@@ -41,38 +41,6 @@ ...@@ -41,38 +41,6 @@
#define FUTEX_WAKE 1 #define FUTEX_WAKE 1
#define FUTEX_PRIVATE_FLAG 128 #define FUTEX_PRIVATE_FLAG 128
// Note: Instead of making direct system calls that are inlined, we rely
// on the syscall() function in glibc to do the right thing. This
// is necessary to make the code compatible with the seccomp sandbox,
// which needs to be able to find and patch all places where system
// calls are made. Scanning through and patching glibc is fast, but
// doing so on the entire Chrome binary would be prohibitively
// expensive.
// This is a notable change from the upstream version of tcmalloc,
// which prefers direct system calls in order to improve compatibility
// with older toolchains and runtime libraries.
static bool have_futex;
static int futex_private_flag = FUTEX_PRIVATE_FLAG;
namespace {
static struct InitModule {
InitModule() {
int x = 0;
// futexes are ints, so we can use them only when
// that's the same size as the lockword_ in SpinLock.
have_futex = (sizeof (Atomic32) == sizeof (int) &&
syscall(__NR_futex, &x, FUTEX_WAKE, 1, 0) >= 0);
if (have_futex &&
syscall(__NR_futex, &x, FUTEX_WAKE | futex_private_flag, 1, 0) < 0) {
futex_private_flag = 0;
}
}
} init_module;
} // anonymous namespace
namespace base { namespace base {
namespace internal { namespace internal {
...@@ -81,28 +49,21 @@ void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) { ...@@ -81,28 +49,21 @@ void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
int save_errno = errno; int save_errno = errno;
struct timespec tm; struct timespec tm;
tm.tv_sec = 0; tm.tv_sec = 0;
if (have_futex) { // Wait between 0-16ms.
// Wait between 0-16ms. tm.tv_nsec = base::internal::SuggestedDelayNS(loop);
tm.tv_nsec = base::internal::SuggestedDelayNS(loop); // Note: since Unlock() is optimized to not do a compare-and-swap,
// Note: since Unlock() is optimized to not do a compare-and-swap, // we can't expect explicit wake-ups. Therefore we shouldn't wait too
// we can't expect explicit wake-ups. Therefore we shouldn't wait too // long here.
// long here. syscall(__NR_futex, reinterpret_cast<int*>(const_cast<Atomic32*>(w)),
syscall(__NR_futex, reinterpret_cast<int *>(const_cast<Atomic32 *>(w)), FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value,
FUTEX_WAIT | futex_private_flag, reinterpret_cast<struct kernel_timespec*>(&tm));
value, reinterpret_cast<struct kernel_timespec *>(&tm));
} else {
tm.tv_nsec = 2000001; // above 2ms so linux 2.4 doesn't spin
nanosleep(&tm, NULL);
}
errno = save_errno; errno = save_errno;
} }
} }
void SpinLockWake(volatile Atomic32 *w, bool all) { void SpinLockWake(volatile Atomic32 *w, bool all) {
if (have_futex) { syscall(__NR_futex, reinterpret_cast<int*>(const_cast<Atomic32*>(w)),
syscall(__NR_futex, reinterpret_cast<int *>(const_cast<Atomic32 *>(w)), FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, 0);
FUTEX_WAKE | futex_private_flag, 1, 0);
}
} }
} // namespace internal } // namespace internal
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment