summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnil Madhavapeddy <anil@recoil.org>2023-05-15 16:59:09 +0100
committerGitHub <noreply@github.com>2023-05-15 16:59:09 +0100
commitcd01cac2e11706cac40462f185345848596f2b40 (patch)
tree2e551319e1615aa738c472b5dd7cd2551dfffd50
parent3358a2eb61128fff9d6f28466d7d50c1bf1ee24d (diff)
downloadocaml-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--Changes3
-rwxr-xr-xconfigure13
-rw-r--r--configure.ac4
-rw-r--r--runtime/caml/osdeps.h2
-rw-r--r--runtime/caml/s.h.in2
-rw-r--r--runtime/unix.c27
-rw-r--r--runtime/win32.c4
7 files changed, 23 insertions, 32 deletions
diff --git a/Changes b/Changes
index 1559c7b732..d53f654bce 100644
--- a/Changes
+++ b/Changes
@@ -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:
diff --git a/configure b/configure
index 75fd072a3b..176087a161 100755
--- a/configure
+++ b/configure
@@ -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)