Commit 483f53e4 authored by zyearn's avatar zyearn

- use native clock_gettime after macos 10.12

- fix the initialization order problem of s_futex_map
parent 25e93185
......@@ -450,11 +450,7 @@ int pthread_fd_wait(int fd, unsigned events,
int diff_ms = -1;
if (abstime) {
timespec now;
#ifdef __MACH__
clock_gettime(CALENDAR_CLOCK, &now);
#else
clock_gettime(CLOCK_REALTIME, &now);
#endif
int64_t now_us = butil::timespec_to_microseconds(now);
int64_t abstime_us = butil::timespec_to_microseconds(*abstime);
if (abstime_us <= now_us) {
......
......@@ -45,12 +45,25 @@ public:
int32_t ref;
};
static std::unordered_map<void*, SimuFutex> s_futex_map;
static pthread_mutex_t s_futex_map_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_once_t init_futex_map_once = PTHREAD_ONCE_INIT;
static std::unordered_map<void*, SimuFutex>* s_futex_map = NULL;
static void InitFutexMap() {
// Leave memory to process's clean up.
s_futex_map = new (std::nothrow) std::unordered_map<void*, SimuFutex>();
if (NULL == s_futex_map) {
exit(1);
}
return;
}
int futex_wait_private(void* addr1, int expected, const timespec* timeout) {
if (pthread_once(&init_futex_map_once, InitFutexMap) != 0) {
LOG(FATAL) << "Fail to pthread_once";
exit(1);
}
std::unique_lock<pthread_mutex_t> mu(s_futex_map_mutex);
SimuFutex& simu_futex = s_futex_map[addr1];
SimuFutex& simu_futex = (*s_futex_map)[addr1];
++simu_futex.ref;
mu.unlock();
......@@ -80,16 +93,20 @@ int futex_wait_private(void* addr1, int expected, const timespec* timeout) {
std::unique_lock<pthread_mutex_t> mu1(s_futex_map_mutex);
if (--simu_futex.ref == 0) {
s_futex_map.erase(addr1);
s_futex_map->erase(addr1);
}
mu1.unlock();
return rc;
}
int futex_wake_private(void* addr1, int nwake) {
if (pthread_once(&init_futex_map_once, InitFutexMap) != 0) {
LOG(FATAL) << "Fail to pthread_once";
exit(1);
}
std::unique_lock<pthread_mutex_t> mu(s_futex_map_mutex);
auto it = s_futex_map.find(addr1);
if (it == s_futex_map.end()) {
auto it = s_futex_map->find(addr1);
if (it == s_futex_map->end()) {
return 0;
}
SimuFutex& simu_futex = it->second;
......@@ -113,7 +130,7 @@ int futex_wake_private(void* addr1, int nwake) {
std::unique_lock<pthread_mutex_t> mu2(s_futex_map_mutex);
if (--simu_futex.ref == 0) {
s_futex_map.erase(addr1);
s_futex_map->erase(addr1);
}
mu2.unlock();
return nwakedup;
......
......@@ -35,13 +35,7 @@ int64_t monotonic_time_ns() {
// use the RAW version does not make sense anymore.
// NOTE: Not inline to keep ABI-compatible with previous versions.
timespec now;
#ifdef __MACH__
// The value returned is a monotonically increasing value according to
// https://opensource.apple.com/source/xnu/xnu-792.13.8/osfmk/man/clock_get_time.html
clock_gettime(CALENDAR_CLOCK, &now);
#else
clock_gettime(CLOCK_MONOTONIC, &now);
#endif
return now.tv_sec * 1000000000L + now.tv_nsec;
}
......
......@@ -28,7 +28,12 @@
#include <mach/clock.h>
#include <mach/mach.h>
inline int clock_gettime(clock_id_t id, timespec* time) {
# ifndef clock_gettime
# define CLOCK_REALTIME CALENDAR_CLOCK
# define CLOCK_MONOTONIC SYSTEM_CLOCK
typedef int clockid_t;
inline int clock_gettime(clockid_t id, timespec* time) {
// clock_gettime is not available in MacOS, use clock_get_time instead
clock_serv_t cclock;
mach_timespec_t mts;
......@@ -39,6 +44,7 @@ inline int clock_gettime(clock_id_t id, timespec* time) {
time->tv_nsec = mts.tv_nsec;
return 0;
}
# endif
#endif
namespace butil {
......@@ -104,11 +110,7 @@ inline timespec seconds_from(timespec start_time, int64_t seconds) {
// --------------------------------------------------------------------
inline timespec nanoseconds_from_now(int64_t nanoseconds) {
timespec time;
#ifdef __MACH__
clock_gettime(CALENDAR_CLOCK, &time);
#else
clock_gettime(CLOCK_REALTIME, &time);
#endif
return nanoseconds_from(time, nanoseconds);
}
......@@ -126,11 +128,7 @@ inline timespec seconds_from_now(int64_t seconds) {
inline timespec timespec_from_now(const timespec& span) {
timespec time;
#ifdef __MACH__
clock_gettime(CALENDAR_CLOCK, &time);
#else
clock_gettime(CLOCK_REALTIME, &time);
#endif
timespec_add(&time, span);
return time;
}
......
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