mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-22 04:03:11 +00:00
Detect monotonic condvar support at configure time
This commit is contained in:
committed by
Guangli Dai
parent
ebacec3a1a
commit
8361239b03
37
configure.ac
37
configure.ac
@@ -2224,6 +2224,43 @@ dnl Check if we have dlsym support.
|
|||||||
if test "x${je_cv_pthread_get_name_np}" = "xyes" ; then
|
if test "x${je_cv_pthread_get_name_np}" = "xyes" ; then
|
||||||
AC_DEFINE([JEMALLOC_HAVE_PTHREAD_GET_NAME_NP], [ ], [ ])
|
AC_DEFINE([JEMALLOC_HAVE_PTHREAD_GET_NAME_NP], [ ], [ ])
|
||||||
fi
|
fi
|
||||||
|
dnl Runtime-check pthread_condattr_setclock and clock_gettime with
|
||||||
|
dnl CLOCK_MONOTONIC to confirm the kernel actually supports the
|
||||||
|
dnl monotonic clock.
|
||||||
|
AC_CACHE_CHECK([whether pthread_condattr_setclock with CLOCK_MONOTONIC is usable],
|
||||||
|
[je_cv_pthread_cond_timedwait_monotonic],
|
||||||
|
AC_RUN_IFELSE([AC_LANG_PROGRAM(
|
||||||
|
[[
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <time.h>
|
||||||
|
]], [[
|
||||||
|
pthread_condattr_t attr;
|
||||||
|
pthread_cond_t cond;
|
||||||
|
struct timespec ts;
|
||||||
|
int ret = pthread_condattr_init(&attr);
|
||||||
|
if (ret != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ret = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
|
||||||
|
if (ret != 0) {
|
||||||
|
pthread_condattr_destroy(&attr);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ret = pthread_cond_init(&cond, &attr);
|
||||||
|
pthread_condattr_destroy(&attr);
|
||||||
|
if (ret != 0) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ret = clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
pthread_cond_destroy(&cond);
|
||||||
|
return ret != 0;
|
||||||
|
]])],
|
||||||
|
[je_cv_pthread_cond_timedwait_monotonic=yes],
|
||||||
|
[je_cv_pthread_cond_timedwait_monotonic=no],
|
||||||
|
[je_cv_pthread_cond_timedwait_monotonic=no]))
|
||||||
|
if test "x${je_cv_pthread_cond_timedwait_monotonic}" = "xyes" ; then
|
||||||
|
AC_DEFINE([JEMALLOC_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC], [ ], [ ])
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
JE_APPEND_VS(CPPFLAGS, -D_REENTRANT)
|
JE_APPEND_VS(CPPFLAGS, -D_REENTRANT)
|
||||||
|
|||||||
@@ -97,6 +97,9 @@
|
|||||||
/* Defined if pthread_get_name_np(3) is available. */
|
/* Defined if pthread_get_name_np(3) is available. */
|
||||||
#undef JEMALLOC_HAVE_PTHREAD_GET_NAME_NP
|
#undef JEMALLOC_HAVE_PTHREAD_GET_NAME_NP
|
||||||
|
|
||||||
|
/* Defined if pthread_condattr_setclock(..., CLOCK_MONOTONIC) is available. */
|
||||||
|
#undef JEMALLOC_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defined if clock_gettime(CLOCK_MONOTONIC_COARSE, ...) is available.
|
* Defined if clock_gettime(CLOCK_MONOTONIC_COARSE, ...) is available.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -191,6 +191,50 @@ background_thread_cond_wait(
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
background_thread_cond_init(pthread_cond_t *cond) {
|
||||||
|
#ifdef JEMALLOC_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
|
||||||
|
pthread_condattr_t cond_attr;
|
||||||
|
int ret = pthread_condattr_init(&cond_attr);
|
||||||
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
|
||||||
|
if (ret != 0) {
|
||||||
|
pthread_condattr_destroy(&cond_attr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = pthread_cond_init(cond, &cond_attr);
|
||||||
|
pthread_condattr_destroy(&cond_attr);
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
return pthread_cond_init(cond, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fill in the absolute deadline for pthread_cond_timedwait. The clock read
|
||||||
|
* here MUST match the clock the condvar was initialized with in
|
||||||
|
* background_thread_cond_init, otherwise the deadline is interpreted against
|
||||||
|
* the wrong epoch.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
background_thread_wakeup_ts_init(struct timespec *ts, uint64_t interval) {
|
||||||
|
nstime_t wakeup;
|
||||||
|
#ifdef JEMALLOC_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC
|
||||||
|
struct timespec now;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
nstime_init2(&wakeup, now.tv_sec, now.tv_nsec);
|
||||||
|
#else
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
nstime_init2(&wakeup, tv.tv_sec, tv.tv_usec * 1000);
|
||||||
|
#endif
|
||||||
|
nstime_iadd(&wakeup, interval);
|
||||||
|
ts->tv_sec = (size_t)nstime_sec(&wakeup);
|
||||||
|
ts->tv_nsec = (size_t)nstime_nsec(&wakeup);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
background_thread_sleep(
|
background_thread_sleep(
|
||||||
tsdn_t *tsdn, background_thread_info_t *info, uint64_t interval) {
|
tsdn_t *tsdn, background_thread_info_t *info, uint64_t interval) {
|
||||||
@@ -220,12 +264,8 @@ background_thread_sleep(
|
|||||||
background_thread_wakeup_time_set(
|
background_thread_wakeup_time_set(
|
||||||
tsdn, info, nstime_ns(&next_wakeup));
|
tsdn, info, nstime_ns(&next_wakeup));
|
||||||
|
|
||||||
nstime_t ts_wakeup;
|
|
||||||
nstime_copy(&ts_wakeup, &before_sleep);
|
|
||||||
nstime_iadd(&ts_wakeup, interval);
|
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
ts.tv_sec = (size_t)nstime_sec(&ts_wakeup);
|
background_thread_wakeup_ts_init(&ts, interval);
|
||||||
ts.tv_nsec = (size_t)nstime_nsec(&ts_wakeup);
|
|
||||||
|
|
||||||
assert(!background_thread_indefinite_sleep(info));
|
assert(!background_thread_indefinite_sleep(info));
|
||||||
ret = background_thread_cond_wait(info, &ts);
|
ret = background_thread_cond_wait(info, &ts);
|
||||||
@@ -747,27 +787,7 @@ background_thread_postfork_child(tsdn_t *tsdn) {
|
|||||||
background_thread_info_t *info = &background_thread_info[i];
|
background_thread_info_t *info = &background_thread_info[i];
|
||||||
malloc_mutex_lock(tsdn, &info->mtx);
|
malloc_mutex_lock(tsdn, &info->mtx);
|
||||||
info->state = background_thread_stopped;
|
info->state = background_thread_stopped;
|
||||||
#if defined(JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE) || defined(JEMALLOC_HAVE_CLOCK_MONOTONIC)
|
int ret = background_thread_cond_init(&info->cond);
|
||||||
int ret;
|
|
||||||
pthread_condattr_t cond_attr;
|
|
||||||
if (pthread_condattr_init(&cond_attr)) {
|
|
||||||
ret = pthread_cond_init(&info->cond, NULL);
|
|
||||||
} else if (pthread_condattr_setclock(&cond_attr,
|
|
||||||
CLOCK_MONOTONIC)) {
|
|
||||||
/*
|
|
||||||
* Fall back to default (CLOCK_REALTIME)
|
|
||||||
* attributes if setclock fails.
|
|
||||||
*/
|
|
||||||
pthread_condattr_destroy(&cond_attr);
|
|
||||||
ret = pthread_cond_init(&info->cond, NULL);
|
|
||||||
} else {
|
|
||||||
ret = pthread_cond_init(&info->cond,
|
|
||||||
&cond_attr);
|
|
||||||
pthread_condattr_destroy(&cond_attr);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int ret = pthread_cond_init(&info->cond, NULL);
|
|
||||||
#endif
|
|
||||||
assert(ret == 0);
|
assert(ret == 0);
|
||||||
background_thread_info_init(tsdn, info);
|
background_thread_info_init(tsdn, info);
|
||||||
malloc_mutex_unlock(tsdn, &info->mtx);
|
malloc_mutex_unlock(tsdn, &info->mtx);
|
||||||
@@ -885,28 +905,9 @@ background_thread_boot1(tsdn_t *tsdn, base_t *base) {
|
|||||||
malloc_mutex_address_ordered)) {
|
malloc_mutex_address_ordered)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#if defined(JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE) || defined(JEMALLOC_HAVE_CLOCK_MONOTONIC)
|
if (background_thread_cond_init(&info->cond)) {
|
||||||
{
|
|
||||||
pthread_condattr_t cond_attr;
|
|
||||||
if (pthread_condattr_init(&cond_attr)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (pthread_condattr_setclock(&cond_attr,
|
|
||||||
CLOCK_MONOTONIC)) {
|
|
||||||
pthread_condattr_destroy(&cond_attr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (pthread_cond_init(&info->cond, &cond_attr)) {
|
|
||||||
pthread_condattr_destroy(&cond_attr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
pthread_condattr_destroy(&cond_attr);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (pthread_cond_init(&info->cond, NULL)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
malloc_mutex_lock(tsdn, &info->mtx);
|
malloc_mutex_lock(tsdn, &info->mtx);
|
||||||
info->state = background_thread_stopped;
|
info->state = background_thread_stopped;
|
||||||
background_thread_info_init(tsdn, info);
|
background_thread_info_init(tsdn, info);
|
||||||
|
|||||||
Reference in New Issue
Block a user