| Index: third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h
|
| ===================================================================
|
| --- third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h (revision 88335)
|
| +++ third_party/tcmalloc/chromium/src/base/spinlock_linux-inl.h (working copy)
|
| @@ -28,11 +28,13 @@
|
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| *
|
| * ---
|
| - * This file is a Linux-specific part of spinlock.cc
|
| + * This file is a Linux-specific part of spinlock_internal.cc
|
| */
|
|
|
| #include <sched.h>
|
| #include <time.h>
|
| +#include <limits.h>
|
| +#include "base/linux_syscall_support.h"
|
|
|
| #define FUTEX_WAIT 0
|
| #define FUTEX_WAKE 1
|
| @@ -58,44 +60,54 @@
|
| int x = 0;
|
| // futexes are ints, so we can use them only when
|
| // that's the same size as the lockword_ in SpinLock.
|
| +#ifdef __arm__
|
| + // ARM linux doesn't support sys_futex1(void*, int, int, struct timespec*);
|
| + have_futex = 0;
|
| +#else
|
| have_futex = (sizeof (Atomic32) == sizeof (int) &&
|
| syscall(__NR_futex, &x, FUTEX_WAKE, 1, 0) >= 0);
|
| +#endif
|
| if (have_futex &&
|
| syscall(__NR_futex, &x, FUTEX_WAKE | futex_private_flag, 1, 0) < 0) {
|
| futex_private_flag = 0;
|
| }
|
| }
|
| } init_module;
|
| +
|
| } // anonymous namespace
|
|
|
| -static void SpinLockWait(volatile Atomic32 *w) {
|
| - int save_errno = errno;
|
| - struct timespec tm;
|
| - tm.tv_sec = 0;
|
| - if (have_futex) {
|
| - int value;
|
| - tm.tv_nsec = 1000000; // 1ms; really we're trying to sleep for one kernel
|
| - // clock tick
|
| - while ((value = base::subtle::Acquire_CompareAndSwap(w, 0, 1)) != 0) {
|
| +
|
| +namespace base {
|
| +namespace internal {
|
| +
|
| +void SpinLockDelay(volatile Atomic32 *w, int32 value, int loop) {
|
| + if (loop != 0) {
|
| + int save_errno = errno;
|
| + struct timespec tm;
|
| + tm.tv_sec = 0;
|
| + if (have_futex) {
|
| + tm.tv_nsec = 1000000; // 1ms; really we're trying to sleep for one
|
| + // kernel clock tick
|
| + } else {
|
| + tm.tv_nsec = 2000001; // above 2ms so linux 2.4 doesn't spin
|
| + }
|
| + if (have_futex) {
|
| syscall(__NR_futex, reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),
|
| - FUTEX_WAIT | futex_private_flag,
|
| - value, reinterpret_cast<struct kernel_timespec *>(&tm));
|
| - }
|
| - } else {
|
| - tm.tv_nsec = 2000001; // above 2ms so linux 2.4 doesn't spin
|
| - if (base::subtle::NoBarrier_Load(w) != 0) {
|
| - sched_yield();
|
| - }
|
| - while (base::subtle::Acquire_CompareAndSwap(w, 0, 1) != 0) {
|
| + FUTEX_WAIT | futex_private_flag,
|
| + value, reinterpret_cast<struct kernel_timespec *>(&tm));
|
| + } else {
|
| nanosleep(&tm, NULL);
|
| }
|
| + errno = save_errno;
|
| }
|
| - errno = save_errno;
|
| }
|
|
|
| -static void SpinLockWake(volatile Atomic32 *w) {
|
| +void SpinLockWake(volatile Atomic32 *w, bool all) {
|
| if (have_futex) {
|
| syscall(__NR_futex, reinterpret_cast<int *>(const_cast<Atomic32 *>(w)),
|
| FUTEX_WAKE | futex_private_flag, 1, 0);
|
| }
|
| }
|
| +
|
| +} // namespace internal
|
| +} // namespace base
|
|
|