From c5b082c47013bd9f27833763a99b3d3de9e807e7 Mon Sep 17 00:00:00 2001 From: guangli-dai Date: Mon, 27 Jul 2026 16:30:29 -0700 Subject: [PATCH] Move time facility to OS layer Migrates the Time facility to the OS layer. --- include/jemalloc/internal/os.h | 3 + include/jemalloc/internal/os/posix/time.h | 68 ++++++++++++++++++ include/jemalloc/internal/os/time.h | 29 ++++++++ include/jemalloc/internal/os/windows/time.h | 27 +++++++ src/nstime.c | 80 ++------------------- 5 files changed, 132 insertions(+), 75 deletions(-) create mode 100644 include/jemalloc/internal/os/posix/time.h create mode 100644 include/jemalloc/internal/os/time.h create mode 100644 include/jemalloc/internal/os/windows/time.h diff --git a/include/jemalloc/internal/os.h b/include/jemalloc/internal/os.h index 73e07625..325dbbcd 100644 --- a/include/jemalloc/internal/os.h +++ b/include/jemalloc/internal/os.h @@ -31,4 +31,7 @@ /* File I/O */ #include "jemalloc/internal/os/file.h" +/* Time */ +#include "jemalloc/internal/os/time.h" + #endif /* JEMALLOC_INTERNAL_OS_H */ diff --git a/include/jemalloc/internal/os/posix/time.h b/include/jemalloc/internal/os/posix/time.h new file mode 100644 index 00000000..3949aba9 --- /dev/null +++ b/include/jemalloc/internal/os/posix/time.h @@ -0,0 +1,68 @@ +#ifndef JEMALLOC_INTERNAL_OS_POSIX_TIME_H +#define JEMALLOC_INTERNAL_OS_POSIX_TIME_H + +/* + * POSIX time backend: picks the best available (ideally monotonic) clock, + * falling back to gettimeofday() if nothing better is available. + */ +#include "jemalloc/internal/jemalloc_preamble.h" + +#if defined(JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE) +# define OS_TIME_MONOTONIC 1 +JEMALLOC_ALWAYS_INLINE void +os_time_get(nstime_t *time) { + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); + nstime_init2(time, ts.tv_sec, ts.tv_nsec); +} +#elif defined(JEMALLOC_HAVE_CLOCK_MONOTONIC) +# define OS_TIME_MONOTONIC 1 +JEMALLOC_ALWAYS_INLINE void +os_time_get(nstime_t *time) { + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + nstime_init2(time, ts.tv_sec, ts.tv_nsec); +} +#elif defined(JEMALLOC_HAVE_CLOCK_GETTIME_NSEC_NP) +# define OS_TIME_MONOTONIC 1 +JEMALLOC_ALWAYS_INLINE void +os_time_get(nstime_t *time) { + nstime_init(time, clock_gettime_nsec_np(CLOCK_UPTIME_RAW)); +} +#elif defined(JEMALLOC_HAVE_MACH_ABSOLUTE_TIME) +# define OS_TIME_MONOTONIC 1 +JEMALLOC_ALWAYS_INLINE void +os_time_get(nstime_t *time) { + static mach_timebase_info_data_t sTimebaseInfo; + if (sTimebaseInfo.denom == 0) { + (void)mach_timebase_info(&sTimebaseInfo); + } + nstime_init(time, + mach_absolute_time() * sTimebaseInfo.numer / sTimebaseInfo.denom); +} +#else +# define OS_TIME_MONOTONIC 0 +JEMALLOC_ALWAYS_INLINE void +os_time_get(nstime_t *time) { + struct timeval tv; + + gettimeofday(&tv, NULL); + nstime_init2(time, tv.tv_sec, tv.tv_usec * 1000); +} +#endif + +JEMALLOC_ALWAYS_INLINE void +os_time_get_realtime(nstime_t *time) { +#if defined(JEMALLOC_HAVE_CLOCK_REALTIME) + struct timespec ts; + + clock_gettime(CLOCK_REALTIME, &ts); + nstime_init2(time, ts.tv_sec, ts.tv_nsec); +#else + unreachable(); +#endif +} + +#endif /* JEMALLOC_INTERNAL_OS_POSIX_TIME_H */ diff --git a/include/jemalloc/internal/os/time.h b/include/jemalloc/internal/os/time.h new file mode 100644 index 00000000..4a747e51 --- /dev/null +++ b/include/jemalloc/internal/os/time.h @@ -0,0 +1,29 @@ +#ifndef JEMALLOC_INTERNAL_OS_TIME_H +#define JEMALLOC_INTERNAL_OS_TIME_H + +#include "jemalloc/internal/jemalloc_preamble.h" +#include "jemalloc/internal/os/detect.h" +#include "jemalloc/internal/nstime.h" + +/* + * Time interface. + * Default: posix/. Override: Windows (GetSystemTimeAsFileTime). + * + * Capability macro: OS_TIME_MONOTONIC - 1 iff os_time_get()'s clock never + * goes backwards, 0 otherwise. Defined by whichever backend is selected + * below. + */ + +/* Functions required for implementation in each backend. */ +JEMALLOC_ALWAYS_INLINE void os_time_get(nstime_t *time); +JEMALLOC_ALWAYS_INLINE void os_time_get_realtime(nstime_t *time); + +#if defined(_WIN32) +# include "jemalloc/internal/os/windows/time.h" +#elif defined(JEMALLOC_OS_POSIX) +# include "jemalloc/internal/os/posix/time.h" +#else +# error "OS layer: no time backend for this platform; add os//time.h" +#endif + +#endif /* JEMALLOC_INTERNAL_OS_TIME_H */ diff --git a/include/jemalloc/internal/os/windows/time.h b/include/jemalloc/internal/os/windows/time.h new file mode 100644 index 00000000..5f28c0ab --- /dev/null +++ b/include/jemalloc/internal/os/windows/time.h @@ -0,0 +1,27 @@ +#ifndef JEMALLOC_INTERNAL_OS_WINDOWS_TIME_H +#define JEMALLOC_INTERNAL_OS_WINDOWS_TIME_H + +/* + * Windows time backend, via GetSystemTimeAsFileTime(). Not monotonic. + */ +#include "jemalloc/internal/jemalloc_preamble.h" + +#define OS_TIME_MONOTONIC 0 + +JEMALLOC_ALWAYS_INLINE void +os_time_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); +} + +JEMALLOC_ALWAYS_INLINE void +os_time_get_realtime(nstime_t *time) { + unreachable(); +} + +#endif /* JEMALLOC_INTERNAL_OS_WINDOWS_TIME_H */ diff --git a/src/nstime.c b/src/nstime.c index 585cbfaa..b798f6ef 100644 --- a/src/nstime.c +++ b/src/nstime.c @@ -2,6 +2,7 @@ #include "jemalloc/internal/assert.h" #include "jemalloc/internal/nstime.h" +#include "jemalloc/internal/os.h" #define BILLION UINT64_C(1000000000) #define MILLION UINT64_C(1000000) @@ -192,68 +193,9 @@ nstime_ms_since(const nstime_t *past) { return nstime_ns_since(past) / MILLION; } -#ifdef _WIN32 -# define NSTIME_MONOTONIC false -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 defined(JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE) -# define NSTIME_MONOTONIC true -static void -nstime_get(nstime_t *time) { - struct timespec ts; - - clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); - nstime_init2(time, ts.tv_sec, ts.tv_nsec); -} -#elif defined(JEMALLOC_HAVE_CLOCK_MONOTONIC) -# define NSTIME_MONOTONIC true -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 defined(JEMALLOC_HAVE_CLOCK_GETTIME_NSEC_NP) -# define NSTIME_MONOTONIC true -static void -nstime_get(nstime_t *time) { - nstime_init(time, clock_gettime_nsec_np(CLOCK_UPTIME_RAW)); -} -#elif defined(JEMALLOC_HAVE_MACH_ABSOLUTE_TIME) -# define NSTIME_MONOTONIC true -static void -nstime_get(nstime_t *time) { - static mach_timebase_info_data_t sTimebaseInfo; - if (sTimebaseInfo.denom == 0) { - (void)mach_timebase_info(&sTimebaseInfo); - } - nstime_init(time, - mach_absolute_time() * sTimebaseInfo.numer / sTimebaseInfo.denom); -} -#else -# define NSTIME_MONOTONIC false -static void -nstime_get(nstime_t *time) { - struct timeval tv; - - gettimeofday(&tv, NULL); - nstime_init2(time, tv.tv_sec, tv.tv_usec * 1000); -} -#endif - static bool nstime_monotonic_impl(void) { - return NSTIME_MONOTONIC; -#undef NSTIME_MONOTONIC + return OS_TIME_MONOTONIC; } nstime_monotonic_t *JET_MUTABLE nstime_monotonic = nstime_monotonic_impl; @@ -264,18 +206,6 @@ const char *const prof_time_res_mode_names[] = { "high", }; -static void -nstime_get_realtime(nstime_t *time) { -#if defined(JEMALLOC_HAVE_CLOCK_REALTIME) && !defined(_WIN32) - struct timespec ts; - - clock_gettime(CLOCK_REALTIME, &ts); - nstime_init2(time, ts.tv_sec, ts.tv_nsec); -#else - unreachable(); -#endif -} - static void nstime_prof_update_impl(nstime_t *time) { nstime_t old_time; @@ -283,9 +213,9 @@ nstime_prof_update_impl(nstime_t *time) { nstime_copy(&old_time, time); if (opt_prof_time_res == prof_time_res_high) { - nstime_get_realtime(time); + os_time_get_realtime(time); } else { - nstime_get(time); + os_time_get(time); } } nstime_prof_update_t *JET_MUTABLE nstime_prof_update = nstime_prof_update_impl; @@ -295,7 +225,7 @@ nstime_update_impl(nstime_t *time) { nstime_t old_time; nstime_copy(&old_time, time); - nstime_get(time); + os_time_get(time); /* Handle non-monotonic clocks. */ if (unlikely(nstime_compare(&old_time, time) > 0)) {