From 2a54ec5f27da1fc8110406e8c4385494f55553c9 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Wed, 25 Mar 2026 15:43:28 +0100 Subject: [PATCH 1/3] fix(time): old macos fallback Signed-off-by: Ali Caglayan --- otherlibs/stdune/src/time_stubs.c | 12 ++++++++++++ otherlibs/stdune/src/wait4_stubs.c | 19 +++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/otherlibs/stdune/src/time_stubs.c b/otherlibs/stdune/src/time_stubs.c index 8182dc8ccfd..71db5f8cdbb 100644 --- a/otherlibs/stdune/src/time_stubs.c +++ b/otherlibs/stdune/src/time_stubs.c @@ -37,11 +37,23 @@ CAMLprim value dune_clock_gettime_realtime(value v_unit) { #include +#if defined(__APPLE__) +#include +#include +#endif + CAMLprim value dune_clock_gettime_realtime(value v_unit) { (void)v_unit; +#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 + // macOS < 10.12 doesn't have clock_gettime, use gettimeofday + struct timeval tv; + gettimeofday(&tv, NULL); + int64_t ns = ((int64_t)tv.tv_sec * 1000000000LL) + ((int64_t)tv.tv_usec * 1000LL); +#else struct timespec tp; clock_gettime(CLOCK_REALTIME, &tp); int64_t ns = ((int64_t)tp.tv_sec * 1000000000LL) + (int64_t)tp.tv_nsec; +#endif return Val_long(ns); } diff --git a/otherlibs/stdune/src/wait4_stubs.c b/otherlibs/stdune/src/wait4_stubs.c index 8a007962108..2b3b109f3a3 100644 --- a/otherlibs/stdune/src/wait4_stubs.c +++ b/otherlibs/stdune/src/wait4_stubs.c @@ -27,6 +27,10 @@ void dune_wait4(value v_pid, value flags) { #include #include +#if defined(__APPLE__) +#include +#endif + #define TAG_WEXITED 0 #define TAG_WSIGNALED 1 #define TAG_WSTOPPED 2 @@ -68,7 +72,12 @@ value dune_wait4(value v_pid, value flags) { CAMLlocal2(times, res); int status, cv_flags; +#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 + struct timeval tv; +#else struct timespec tp; +#endif + int64_t time_ns; cv_flags = caml_convert_flag_list(flags, wait_flag_table); pid_t pid = Int_val(v_pid); @@ -78,7 +87,14 @@ value dune_wait4(value v_pid, value flags) { // returns the pid of the terminated process, or -1 on error pid = wait4(pid, &status, cv_flags, &ru); int wait_errno = errno; +#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 + // macOS < 10.12 doesn't have clock_gettime, use gettimeofday + gettimeofday(&tv, NULL); + time_ns = ((int64_t)tv.tv_sec * 1000000000LL) + ((int64_t)tv.tv_usec * 1000LL); +#else clock_gettime(CLOCK_REALTIME, &tp); + time_ns = ((int64_t)tp.tv_sec * 1000000000LL) + (int64_t)tp.tv_nsec; +#endif caml_leave_blocking_section(); if (pid == 0) { CAMLreturn(Val_none); @@ -107,8 +123,7 @@ value dune_wait4(value v_pid, value flags) { res = caml_alloc_tuple(4); Store_field(res, 0, Val_int(pid)); Store_field(res, 1, alloc_process_status(status)); - Store_field(res, 2, - Val_long(((int64_t)tp.tv_sec * 1000000000LL) + (int64_t)tp.tv_nsec)); + Store_field(res, 2, Val_long(time_ns)); Store_field(res, 3, times); CAMLreturn(caml_alloc_some_compat(res)); } From 61a9744bb4d4224e5cf9acb4606d4e1c81a12a84 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Wed, 25 Mar 2026 16:50:37 +0100 Subject: [PATCH 2/3] fix(fsevents): use correct macos availability macros Signed-off-by: Ali Caglayan --- src/fsevents/fsevents_stubs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/fsevents/fsevents_stubs.c b/src/fsevents/fsevents_stubs.c index 3d15d0b5538..82f5fc0ec96 100644 --- a/src/fsevents/fsevents_stubs.c +++ b/src/fsevents/fsevents_stubs.c @@ -10,7 +10,7 @@ #include #endif -#if defined(__APPLE__) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101000 +#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 #include #include @@ -155,7 +155,7 @@ static void dune_fsevents_callback(const FSEventStreamRef streamRef, continue; } CFStringRef cf_path; -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 CFDictionaryRef details = CFArrayGetValueAtIndex(eventPaths, i); cf_path = CFDictionaryGetValue(details, kFSEventStreamEventExtendedDataPathKey); @@ -228,7 +228,7 @@ CAMLprim value dune_fsevents_create(value v_paths, value v_latency, const FSEventStreamEventFlags flags = kFSEventStreamCreateFlagNoDefer | -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 kFSEventStreamCreateFlagUseExtendedData | #endif kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagFileEvents; @@ -385,7 +385,7 @@ static const FSEventStreamEventFlags all_flags[] = { kFSEventStreamEventFlagOwnEvent, kFSEventStreamEventFlagItemIsHardlink, kFSEventStreamEventFlagItemIsLastHardlink, -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101300 kFSEventStreamEventFlagItemCloned, #endif }; From 06d33fc1cebb43b9e144809fb8c5219237b4b456 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Thu, 26 Mar 2026 11:29:19 +0100 Subject: [PATCH 3/3] refactor(time): introduce common dune_clock.h header for timing We move the platform specific timing functions to a common header and share the definition. Signed-off-by: Ali Caglayan --- otherlibs/stdune/src/dune_clock.h | 71 ++++++++++++++++++++++++++++++ otherlibs/stdune/src/time_stubs.c | 55 +---------------------- otherlibs/stdune/src/wait4_stubs.c | 19 +------- 3 files changed, 75 insertions(+), 70 deletions(-) create mode 100644 otherlibs/stdune/src/dune_clock.h diff --git a/otherlibs/stdune/src/dune_clock.h b/otherlibs/stdune/src/dune_clock.h new file mode 100644 index 00000000000..cf0be2db0d0 --- /dev/null +++ b/otherlibs/stdune/src/dune_clock.h @@ -0,0 +1,71 @@ +// Cross-platform realtime clock with legacy fallbacks +// +// Provides dune_clock_gettime_ns() returning nanoseconds since Unix epoch. +// +// Platform support: +// >= Windows 8 GetSystemTimePreciseAsFileTime +// < Windows 8 GetSystemTimeAsFileTime +// >= macOS 10.12 clock_gettime +// < macOS 10.12 gettimeofday +// Other Unix clock_gettime + +#ifndef DUNE_CLOCK_H +#define DUNE_CLOCK_H + +#include + +#ifdef _WIN32 +#include + +// Windows epoch starts 1601-01-01, Unix epoch starts 1970-01-01 +// Difference is 11644473600 seconds +#define SEC_TO_UNIX_EPOCH 11644473600LL + +static inline int64_t dune_clock_gettime_ns(void) { + FILETIME ft; + static VOID (WINAPI *GetSystemTime)(LPFILETIME) = NULL; + + if (GetSystemTime == NULL) { + HMODULE h = GetModuleHandleA("kernel32.dll"); + if (h) { + GetSystemTime = (VOID (WINAPI *)(LPFILETIME))GetProcAddress(h, "GetSystemTimePreciseAsFileTime"); + } + if (GetSystemTime == NULL) { + // Fallback for Windows < 8 + GetSystemTime = GetSystemTimeAsFileTime; + } + } + + GetSystemTime(&ft); + ULARGE_INTEGER li; + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + + // Convert from 100ns intervals since Windows epoch to ns since Unix epoch + return (li.QuadPart - SEC_TO_UNIX_EPOCH * 10000000LL) * 100; +} + +#else // _WIN32 + +#include + +#if defined(__APPLE__) +#include +#include +#endif + +static inline int64_t dune_clock_gettime_ns(void) { +#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 + // macOS < 10.12 doesn't have clock_gettime, use gettimeofday + struct timeval tv; + gettimeofday(&tv, NULL); + return ((int64_t)tv.tv_sec * 1000000000LL) + ((int64_t)tv.tv_usec * 1000LL); +#else + struct timespec tp; + clock_gettime(CLOCK_REALTIME, &tp); + return ((int64_t)tp.tv_sec * 1000000000LL) + (int64_t)tp.tv_nsec; +#endif +} + +#endif // _WIN32 +#endif // DUNE_CLOCK_H diff --git a/otherlibs/stdune/src/time_stubs.c b/otherlibs/stdune/src/time_stubs.c index 71db5f8cdbb..1e4a0f5cb29 100644 --- a/otherlibs/stdune/src/time_stubs.c +++ b/otherlibs/stdune/src/time_stubs.c @@ -1,60 +1,9 @@ #include #include -#include -#ifdef _WIN32 -#include - -// Windows epoch starts 1601-01-01, Unix epoch starts 1970-01-01 -// Difference is 11644473600 seconds -#define SEC_TO_UNIX_EPOCH 11644473600LL +#include "dune_clock.h" CAMLprim value dune_clock_gettime_realtime(value v_unit) { (void)v_unit; - FILETIME ft; - static VOID (WINAPI *GetSystemTime)(LPFILETIME) = NULL; - if (GetSystemTime == NULL) { - HMODULE h = GetModuleHandleA("kernel32.dll"); - if (h) { - GetSystemTime = (VOID (WINAPI *)(LPFILETIME))GetProcAddress(h, "GetSystemTimePreciseAsFileTime"); - } - if (GetSystemTime == NULL) { /* < Windows 8 */ - GetSystemTime = GetSystemTimeAsFileTime; - } - } - - GetSystemTime(&ft); - ULARGE_INTEGER li; - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - - // Convert from 100ns intervals since Windows epoch to ns since Unix epoch - int64_t ns = (li.QuadPart - SEC_TO_UNIX_EPOCH * 10000000LL) * 100; - return Val_long(ns); + return Val_long(dune_clock_gettime_ns()); } - -#else // Unix-like systems - -#include - -#if defined(__APPLE__) -#include -#include -#endif - -CAMLprim value dune_clock_gettime_realtime(value v_unit) { - (void)v_unit; -#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 - // macOS < 10.12 doesn't have clock_gettime, use gettimeofday - struct timeval tv; - gettimeofday(&tv, NULL); - int64_t ns = ((int64_t)tv.tv_sec * 1000000000LL) + ((int64_t)tv.tv_usec * 1000LL); -#else - struct timespec tp; - clock_gettime(CLOCK_REALTIME, &tp); - int64_t ns = ((int64_t)tp.tv_sec * 1000000000LL) + (int64_t)tp.tv_nsec; -#endif - return Val_long(ns); -} - -#endif diff --git a/otherlibs/stdune/src/wait4_stubs.c b/otherlibs/stdune/src/wait4_stubs.c index 2b3b109f3a3..645ebb34adc 100644 --- a/otherlibs/stdune/src/wait4_stubs.c +++ b/otherlibs/stdune/src/wait4_stubs.c @@ -24,12 +24,9 @@ void dune_wait4(value v_pid, value flags) { #include #include #include -#include #include -#if defined(__APPLE__) -#include -#endif +#include "dune_clock.h" #define TAG_WEXITED 0 #define TAG_WSIGNALED 1 @@ -72,11 +69,6 @@ value dune_wait4(value v_pid, value flags) { CAMLlocal2(times, res); int status, cv_flags; -#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 - struct timeval tv; -#else - struct timespec tp; -#endif int64_t time_ns; cv_flags = caml_convert_flag_list(flags, wait_flag_table); pid_t pid = Int_val(v_pid); @@ -87,14 +79,7 @@ value dune_wait4(value v_pid, value flags) { // returns the pid of the terminated process, or -1 on error pid = wait4(pid, &status, cv_flags, &ru); int wait_errno = errno; -#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 - // macOS < 10.12 doesn't have clock_gettime, use gettimeofday - gettimeofday(&tv, NULL); - time_ns = ((int64_t)tv.tv_sec * 1000000000LL) + ((int64_t)tv.tv_usec * 1000LL); -#else - clock_gettime(CLOCK_REALTIME, &tp); - time_ns = ((int64_t)tp.tv_sec * 1000000000LL) + (int64_t)tp.tv_nsec; -#endif + time_ns = dune_clock_gettime_ns(); caml_leave_blocking_section(); if (pid == 0) { CAMLreturn(Val_none);