Merge "Use FUTEX_WAIT_BITSET to avoid converting timeouts."

This commit is contained in:
Yabin Cui
2015-11-21 01:50:29 +00:00
committed by Gerrit Code Review
13 changed files with 346 additions and 203 deletions

View File

@@ -40,10 +40,12 @@ __BEGIN_DECLS
struct timespec;
static inline __always_inline int __futex(volatile void* ftx, int op, int value, const struct timespec* timeout) {
static inline __always_inline int __futex(volatile void* ftx, int op, int value,
const struct timespec* timeout,
int bitset) {
// Our generated syscall assembler sets errno, but our callers (pthread functions) don't want to.
int saved_errno = errno;
int result = syscall(__NR_futex, ftx, op, value, timeout);
int result = syscall(__NR_futex, ftx, op, value, timeout, NULL, bitset);
if (__predict_false(result == -1)) {
result = -errno;
errno = saved_errno;
@@ -52,19 +54,22 @@ static inline __always_inline int __futex(volatile void* ftx, int op, int value,
}
static inline int __futex_wake(volatile void* ftx, int count) {
return __futex(ftx, FUTEX_WAKE, count, NULL);
return __futex(ftx, FUTEX_WAKE, count, NULL, 0);
}
static inline int __futex_wake_ex(volatile void* ftx, bool shared, int count) {
return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL);
return __futex(ftx, shared ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, count, NULL, 0);
}
static inline int __futex_wait(volatile void* ftx, int value, const struct timespec* timeout) {
return __futex(ftx, FUTEX_WAIT, value, timeout);
return __futex(ftx, FUTEX_WAIT, value, timeout, 0);
}
static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value, const struct timespec* timeout) {
return __futex(ftx, shared ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, value, timeout);
static inline int __futex_wait_ex(volatile void* ftx, bool shared, int value,
bool use_realtime_clock, const struct timespec* abs_timeout) {
return __futex(ftx, (shared ? FUTEX_WAIT_BITSET : FUTEX_WAIT_BITSET_PRIVATE) |
(use_realtime_clock ? FUTEX_CLOCK_REALTIME : 0), value, abs_timeout,
FUTEX_BITSET_MATCH_ANY);
}
__END_DECLS

View File

@@ -64,7 +64,7 @@ class Lock {
}
while (atomic_exchange_explicit(&state, LockedWithWaiter, memory_order_acquire) != Unlocked) {
// TODO: As the critical section is brief, it is a better choice to spin a few times befor sleeping.
__futex_wait_ex(&state, process_shared, LockedWithWaiter, NULL);
__futex_wait_ex(&state, process_shared, LockedWithWaiter, false, nullptr);
}
return;
}

View File

@@ -29,9 +29,12 @@
#ifndef _BIONIC_TIME_CONVERSIONS_H
#define _BIONIC_TIME_CONVERSIONS_H
#include <errno.h>
#include <time.h>
#include <sys/cdefs.h>
#include "private/bionic_constants.h"
__BEGIN_DECLS
__LIBC_HIDDEN__ bool timespec_from_timeval(timespec& ts, const timeval& tv);
@@ -39,8 +42,21 @@ __LIBC_HIDDEN__ void timespec_from_ms(timespec& ts, const int ms);
__LIBC_HIDDEN__ void timeval_from_timespec(timeval& tv, const timespec& ts);
__LIBC_HIDDEN__ bool timespec_from_absolute_timespec(timespec& ts, const timespec& abs_ts, clockid_t clock);
__LIBC_HIDDEN__ void absolute_timespec_from_timespec(timespec& abs_ts, const timespec& ts,
clockid_t clock);
__END_DECLS
static inline int check_timespec(const timespec* ts) {
if (ts != nullptr) {
if (ts->tv_nsec < 0 || ts->tv_nsec >= NS_PER_S) {
return EINVAL;
}
if (ts->tv_sec < 0) {
return ETIMEDOUT;
}
}
return 0;
}
#endif