diff options
author | Anil Madhavapeddy <anil@recoil.org> | 2023-05-15 16:59:09 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-15 16:59:09 +0100 |
commit | cd01cac2e11706cac40462f185345848596f2b40 (patch) | |
tree | 2e551319e1615aa738c472b5dd7cd2551dfffd50 | |
parent | 3358a2eb61128fff9d6f28466d7d50c1bf1ee24d (diff) | |
download | ocaml-cd01cac2e11706cac40462f185345848596f2b40.tar.gz |
make caml_time_counter concurrent-safe on macOS (#12234)
Also time counter a uint64_t instead of casting between
signed/unsigned longs on all the platforms. The type
of most of the monotonic counter interfaces is an uint64,
except for Windows.
Fixes #12096
-rw-r--r-- | Changes | 3 | ||||
-rwxr-xr-x | configure | 13 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | runtime/caml/osdeps.h | 2 | ||||
-rw-r--r-- | runtime/caml/s.h.in | 2 | ||||
-rw-r--r-- | runtime/unix.c | 27 | ||||
-rw-r--r-- | runtime/win32.c | 4 |
7 files changed, 23 insertions, 32 deletions
@@ -14,6 +14,9 @@ Working version tables will go in the readonly segment, where they belong. (Antonin Décimo, review by Gabriel Scherer and Xavier Leroy) +- #12234: make instrumented time calculation more thread-safe on macOS. + (Anil Madhavapeddy, review by Daniel Bünzli and Xavier Leroy) + ### Code generation and optimizations: ### Standard library: @@ -16206,18 +16206,15 @@ case $host in #( *-apple-darwin*) : - for ac_func in mach_timebase_info mach_absolute_time + for ac_func in clock_gettime_nsec_np do : - as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes" + ac_fn_c_check_func "$LINENO" "clock_gettime_nsec_np" "ac_cv_func_clock_gettime_nsec_np" +if test "x$ac_cv_func_clock_gettime_nsec_np" = xyes then : - cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF + printf "%s\n" "#define HAVE_CLOCK_GETTIME_NSEC_NP 1" >>confdefs.h has_monotonic_clock=true - printf "%s\n" "#define HAS_MACH_ABSOLUTE_TIME 1" >>confdefs.h + printf "%s\n" "#define HAS_CLOCK_GETTIME_NSEC_NP 1" >>confdefs.h else $as_nop diff --git a/configure.ac b/configure.ac index 5973e93c01..b33c5f977b 100644 --- a/configure.ac +++ b/configure.ac @@ -1484,10 +1484,10 @@ AS_CASE([$host], [*-*-windows], [has_monotonic_clock=true], [*-apple-darwin*], [ - AC_CHECK_FUNCS([mach_timebase_info mach_absolute_time], + AC_CHECK_FUNCS([clock_gettime_nsec_np], [ has_monotonic_clock=true - AC_DEFINE([HAS_MACH_ABSOLUTE_TIME]) + AC_DEFINE([HAS_CLOCK_GETTIME_NSEC_NP]) ], [has_monotonic_clock=false])], [AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ diff --git a/runtime/caml/osdeps.h b/runtime/caml/osdeps.h index c72ccf6ccb..5b028b9200 100644 --- a/runtime/caml/osdeps.h +++ b/runtime/caml/osdeps.h @@ -151,7 +151,7 @@ CAMLextern clock_t caml_win32_clock(void); millisecond). This makes it useful for benchmarking and timeouts, but not for telling the time. The units are always nanoseconds, but the achieved resolution may be less. The starting point is unspecified. */ -extern int64_t caml_time_counter(void); +extern uint64_t caml_time_counter(void); extern void caml_init_os_params(void); diff --git a/runtime/caml/s.h.in b/runtime/caml/s.h.in index 4b5b43ba19..a2800a45fe 100644 --- a/runtime/caml/s.h.in +++ b/runtime/caml/s.h.in @@ -304,7 +304,7 @@ #undef HAS_POSIX_MONOTONIC_CLOCK -#undef HAS_MACH_ABSOLUTE_TIME +#undef HAS_CLOCK_GETTIME_NSEC_NP #undef HAS_GNU_GETAFFINITY_NP #undef HAS_BSD_GETAFFINITY_NP diff --git a/runtime/unix.c b/runtime/unix.c index a71980497c..f4e7b84de5 100644 --- a/runtime/unix.c +++ b/runtime/unix.c @@ -45,8 +45,8 @@ #endif #ifdef HAS_POSIX_MONOTONIC_CLOCK #include <time.h> -#elif HAS_MACH_ABSOLUTE_TIME -#include <mach/mach_time.h> +#elif HAS_CLOCK_GETTIME_NSEC_NP +#include <time.h> #endif #ifdef HAS_DIRENT #include <dirent.h> @@ -431,31 +431,22 @@ char *caml_secure_getenv (char const *var) #endif } -int64_t caml_time_counter(void) +uint64_t caml_time_counter(void) { -#if defined(HAS_MACH_ABSOLUTE_TIME) - static mach_timebase_info_data_t time_base = {0}; - uint64_t now; - - if (time_base.denom == 0) { - if (mach_timebase_info(&time_base) != KERN_SUCCESS) - return 0; - } - - now = mach_absolute_time(); - return (int64_t)((now * time_base.numer) / time_base.denom); +#if defined(HAS_CLOCK_GETTIME_NSEC_NP) + return (clock_gettime_nsec_np(CLOCK_UPTIME_RAW)); #elif defined(HAS_POSIX_MONOTONIC_CLOCK) struct timespec t; clock_gettime(CLOCK_MONOTONIC, &t); return - (int64_t)t.tv_sec * (int64_t)1000000000 + - (int64_t)t.tv_nsec; + (uint64_t)t.tv_sec * (uint64_t)1000000000 + + (uint64_t)t.tv_nsec; #elif defined(HAS_GETTIMEOFDAY) struct timeval t; gettimeofday(&t, 0); return - (int64_t)t.tv_sec * (int64_t)1000000000 + - (int64_t)t.tv_usec * (int64_t)1000; + (uint64_t)t.tv_sec * (uint64_t)1000000000 + + (uint64_t)t.tv_usec * (uint64_t)1000; #else # error "No timesource available" #endif diff --git a/runtime/win32.c b/runtime/win32.c index 90527f01c8..c277c1b8c8 100644 --- a/runtime/win32.c +++ b/runtime/win32.c @@ -1137,12 +1137,12 @@ void caml_init_os_params(void) clock_period = (1000000000.0 / frequency.QuadPart); } -int64_t caml_time_counter(void) +uint64_t caml_time_counter(void) { LARGE_INTEGER now; QueryPerformanceCounter(&now); - return (int64_t)(now.QuadPart * clock_period); + return (uint64_t)(now.QuadPart * clock_period); } void *caml_plat_mem_map(uintnat size, uintnat alignment, int reserve_only) |