Refine nstime_update().
Add missing #include <time.h>. The critical time facilities appear to have been transitively included via unistd.h and sys/time.h, but in principle this omission was capable of having caused clock_gettime(CLOCK_MONOTONIC, ...) to have been overlooked in favor of gettimeofday(), which in turn could cause spurious non-monotonic time updates. Refactor nstime_get() out of nstime_update() and add configure tests for all variants. Add CLOCK_MONOTONIC_RAW support (Linux-specific) and mach_absolute_time() support (OS X-specific). Do not fall back to clock_gettime(CLOCK_REALTIME, ...). This was a fragile Linux-specific workaround, which we're unlikely to use at all now that clock_gettime(CLOCK_MONOTONIC_RAW, ...) is supported, and if we have no choice besides non-monotonic clocks, gettimeofday() is only incrementally worse.
This commit is contained in:
parent
b6c0867142
commit
e0164bc63c
49
configure.ac
49
configure.ac
@ -345,11 +345,11 @@ dnl
|
|||||||
dnl Define cpp macros in CPPFLAGS, rather than doing AC_DEFINE(macro), since the
|
dnl Define cpp macros in CPPFLAGS, rather than doing AC_DEFINE(macro), since the
|
||||||
dnl definitions need to be seen before any headers are included, which is a pain
|
dnl definitions need to be seen before any headers are included, which is a pain
|
||||||
dnl to make happen otherwise.
|
dnl to make happen otherwise.
|
||||||
|
CFLAGS="$CFLAGS"
|
||||||
default_munmap="1"
|
default_munmap="1"
|
||||||
maps_coalesce="1"
|
maps_coalesce="1"
|
||||||
case "${host}" in
|
case "${host}" in
|
||||||
*-*-darwin* | *-*-ios*)
|
*-*-darwin* | *-*-ios*)
|
||||||
CFLAGS="$CFLAGS"
|
|
||||||
abi="macho"
|
abi="macho"
|
||||||
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
||||||
RPATH=""
|
RPATH=""
|
||||||
@ -362,30 +362,26 @@ case "${host}" in
|
|||||||
sbrk_deprecated="1"
|
sbrk_deprecated="1"
|
||||||
;;
|
;;
|
||||||
*-*-freebsd*)
|
*-*-freebsd*)
|
||||||
CFLAGS="$CFLAGS"
|
|
||||||
abi="elf"
|
abi="elf"
|
||||||
AC_DEFINE([JEMALLOC_SYSCTL_VM_OVERCOMMIT], [ ])
|
AC_DEFINE([JEMALLOC_SYSCTL_VM_OVERCOMMIT], [ ])
|
||||||
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
||||||
force_lazy_lock="1"
|
force_lazy_lock="1"
|
||||||
;;
|
;;
|
||||||
*-*-dragonfly*)
|
*-*-dragonfly*)
|
||||||
CFLAGS="$CFLAGS"
|
|
||||||
abi="elf"
|
abi="elf"
|
||||||
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
||||||
;;
|
;;
|
||||||
*-*-openbsd*)
|
*-*-openbsd*)
|
||||||
CFLAGS="$CFLAGS"
|
|
||||||
abi="elf"
|
abi="elf"
|
||||||
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
||||||
force_tls="0"
|
force_tls="0"
|
||||||
;;
|
;;
|
||||||
*-*-bitrig*)
|
*-*-bitrig*)
|
||||||
CFLAGS="$CFLAGS"
|
|
||||||
abi="elf"
|
abi="elf"
|
||||||
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
||||||
;;
|
;;
|
||||||
*-*-linux*)
|
*-*-linux*)
|
||||||
CFLAGS="$CFLAGS"
|
dnl secure_getenv() is exposed by _GNU_SOURCE.
|
||||||
CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
|
CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
|
||||||
abi="elf"
|
abi="elf"
|
||||||
AC_DEFINE([JEMALLOC_HAS_ALLOCA_H])
|
AC_DEFINE([JEMALLOC_HAS_ALLOCA_H])
|
||||||
@ -404,13 +400,12 @@ case "${host}" in
|
|||||||
#error aout
|
#error aout
|
||||||
#endif
|
#endif
|
||||||
]])],
|
]])],
|
||||||
[CFLAGS="$CFLAGS"; abi="elf"],
|
[abi="elf"],
|
||||||
[abi="aout"])
|
[abi="aout"])
|
||||||
AC_MSG_RESULT([$abi])
|
AC_MSG_RESULT([$abi])
|
||||||
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
||||||
;;
|
;;
|
||||||
*-*-solaris2*)
|
*-*-solaris2*)
|
||||||
CFLAGS="$CFLAGS"
|
|
||||||
abi="elf"
|
abi="elf"
|
||||||
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
||||||
RPATH='-Wl,-R,$(1)'
|
RPATH='-Wl,-R,$(1)'
|
||||||
@ -1309,6 +1304,44 @@ if test "x$je_cv_cray_prgenv_wrapper" = "xyes" ; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl check for CLOCK_MONOTONIC_RAW (Linux-specific).
|
||||||
|
JE_COMPILABLE([clock_gettime(CLOCK_MONOTONIC_RAW, ...)], [
|
||||||
|
#include <time.h>
|
||||||
|
], [
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||||
|
], [je_cv_clock_monotonic_raw])
|
||||||
|
if test "x${je_cv_clock_monotonic_raw}" = "xyes" ; then
|
||||||
|
AC_DEFINE([JEMALLOC_HAVE_CLOCK_MONOTONIC_RAW])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl check for CLOCK_MONOTONIC.
|
||||||
|
JE_COMPILABLE([clock_gettime(CLOCK_MONOTONIC, ...)], [
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
], [
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
#if !defined(_POSIX_MONOTONIC_CLOCK) || _POSIX_MONOTONIC_CLOCK < 0
|
||||||
|
# error _POSIX_MONOTONIC_CLOCK missing/invalid
|
||||||
|
#endif
|
||||||
|
], [je_cv_clock_monotonic])
|
||||||
|
if test "x${je_cv_clock_monotonic}" = "xyes" ; then
|
||||||
|
AC_DEFINE([JEMALLOC_HAVE_CLOCK_MONOTONIC])
|
||||||
|
fi
|
||||||
|
|
||||||
|
dnl Check for mach_absolute_time().
|
||||||
|
JE_COMPILABLE([mach_absolute_time()], [
|
||||||
|
#include <mach/mach_time.h>
|
||||||
|
], [
|
||||||
|
mach_absolute_time();
|
||||||
|
], [je_cv_mach_absolute_time])
|
||||||
|
if test "x${je_cv_mach_absolute_time}" = "xyes" ; then
|
||||||
|
AC_DEFINE([JEMALLOC_HAVE_MACH_ABSOLUTE_TIME])
|
||||||
|
fi
|
||||||
|
|
||||||
dnl Check if the GNU-specific secure_getenv function exists.
|
dnl Check if the GNU-specific secure_getenv function exists.
|
||||||
AC_CHECK_FUNC([secure_getenv],
|
AC_CHECK_FUNC([secure_getenv],
|
||||||
[have_secure_getenv="1"],
|
[have_secure_getenv="1"],
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
# include <sys/time.h>
|
# include <sys/time.h>
|
||||||
|
# include <time.h>
|
||||||
|
# ifdef JEMALLOC_HAVE_MACH_ABSOLUTE_TIME
|
||||||
|
# include <mach/mach_time.h>
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -76,6 +76,21 @@
|
|||||||
*/
|
*/
|
||||||
#undef JEMALLOC_HAVE_ISSETUGID
|
#undef JEMALLOC_HAVE_ISSETUGID
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defined if clock_gettime(CLOCK_MONOTONIC_RAW, ...) is available.
|
||||||
|
*/
|
||||||
|
#undef JEMALLOC_HAVE_CLOCK_MONOTONIC_RAW
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defined if clock_gettime(CLOCK_MONOTONIC, ...) is available.
|
||||||
|
*/
|
||||||
|
#undef JEMALLOC_HAVE_CLOCK_MONOTONIC
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Defined if mach_absolute_time() is available.
|
||||||
|
*/
|
||||||
|
#undef JEMALLOC_HAVE_MACH_ABSOLUTE_TIME
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defined if _malloc_thread_cleanup() exists. At least in the case of
|
* Defined if _malloc_thread_cleanup() exists. At least in the case of
|
||||||
* FreeBSD, pthread_key_create() allocates, which if used during malloc
|
* FreeBSD, pthread_key_create() allocates, which if used during malloc
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
#ifdef JEMALLOC_H_TYPES
|
#ifdef JEMALLOC_H_TYPES
|
||||||
|
|
||||||
#define JEMALLOC_CLOCK_GETTIME defined(_POSIX_MONOTONIC_CLOCK) \
|
|
||||||
&& _POSIX_MONOTONIC_CLOCK >= 0
|
|
||||||
|
|
||||||
typedef struct nstime_s nstime_t;
|
typedef struct nstime_s nstime_t;
|
||||||
|
|
||||||
/* Maximum supported number of seconds (~584 years). */
|
/* Maximum supported number of seconds (~584 years). */
|
||||||
|
76
src/nstime.c
76
src/nstime.c
@ -97,6 +97,54 @@ nstime_divide(const nstime_t *time, const nstime_t *divisor)
|
|||||||
return (time->ns / divisor->ns);
|
return (time->ns / divisor->ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
static void
|
||||||
|
nstime_get(nstime_t *time)
|
||||||
|
{
|
||||||
|
FILETIME ft;
|
||||||
|
uint64_t ticks_100ns;
|
||||||
|
|
||||||
|
GetSystemTimeAsFileTime(&ft);
|
||||||
|
ticks_100ns = (((uint64_t)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
|
||||||
|
|
||||||
|
nstime_init(time, ticks_100ns * 100);
|
||||||
|
}
|
||||||
|
#elif JEMALLOC_HAVE_CLOCK_MONOTONIC_RAW
|
||||||
|
static void
|
||||||
|
nstime_get(nstime_t *time)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||||
|
nstime_init2(time, ts.tv_sec, ts.tv_nsec);
|
||||||
|
}
|
||||||
|
#elif JEMALLOC_HAVE_CLOCK_MONOTONIC
|
||||||
|
static void
|
||||||
|
nstime_get(nstime_t *time)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
nstime_init2(time, ts.tv_sec, ts.tv_nsec);
|
||||||
|
}
|
||||||
|
#elif JEMALLOC_HAVE_MACH_ABSOLUTE_TIME
|
||||||
|
static void
|
||||||
|
nstime_get(nstime_t *time)
|
||||||
|
{
|
||||||
|
|
||||||
|
nstime_init(time, mach_absolute_time());
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static void
|
||||||
|
nstime_get(nstime_t *time)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
nstime_init2(time, tv.tv_sec, tv.tv_usec * 1000);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef JEMALLOC_JET
|
#ifdef JEMALLOC_JET
|
||||||
#undef nstime_update
|
#undef nstime_update
|
||||||
#define nstime_update JEMALLOC_N(n_nstime_update)
|
#define nstime_update JEMALLOC_N(n_nstime_update)
|
||||||
@ -107,33 +155,7 @@ nstime_update(nstime_t *time)
|
|||||||
nstime_t old_time;
|
nstime_t old_time;
|
||||||
|
|
||||||
nstime_copy(&old_time, time);
|
nstime_copy(&old_time, time);
|
||||||
|
nstime_get(time);
|
||||||
#ifdef _WIN32
|
|
||||||
{
|
|
||||||
FILETIME ft;
|
|
||||||
uint64_t ticks;
|
|
||||||
GetSystemTimeAsFileTime(&ft);
|
|
||||||
ticks = (((uint64_t)ft.dwHighDateTime) << 32) |
|
|
||||||
ft.dwLowDateTime;
|
|
||||||
time->ns = ticks * 100;
|
|
||||||
}
|
|
||||||
#elif JEMALLOC_CLOCK_GETTIME
|
|
||||||
{
|
|
||||||
struct timespec ts;
|
|
||||||
|
|
||||||
if (sysconf(_SC_MONOTONIC_CLOCK) > 0)
|
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
||||||
else
|
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
|
||||||
time->ns = ts.tv_sec * BILLION + ts.tv_nsec;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
time->ns = tv.tv_sec * BILLION + tv.tv_usec * 1000;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Handle non-monotonic clocks. */
|
/* Handle non-monotonic clocks. */
|
||||||
if (unlikely(nstime_compare(&old_time, time) > 0)) {
|
if (unlikely(nstime_compare(&old_time, time) > 0)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user