Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions otherlibs/stdune/src/dune_clock.h
Original file line number Diff line number Diff line change
@@ -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 <stdint.h>

#ifdef _WIN32
#include <windows.h>

// 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 <time.h>

#if defined(__APPLE__)
#include <sys/time.h>
#include <AvailabilityMacros.h>
#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
43 changes: 2 additions & 41 deletions otherlibs/stdune/src/time_stubs.c
Original file line number Diff line number Diff line change
@@ -1,48 +1,9 @@
#include <caml/mlvalues.h>
#include <caml/alloc.h>
#include <stdint.h>

#ifdef _WIN32
#include <windows.h>

// Windows epoch starts 1601-01-01, Unix epoch starts 1970-01-01
// Difference is 11644473600 seconds
#define SEC_TO_UNIX_EPOCH 11644473600LL

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);
}

#else // Unix-like systems

#include <time.h>
#include "dune_clock.h"

CAMLprim value dune_clock_gettime_realtime(value v_unit) {
(void)v_unit;
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
int64_t ns = ((int64_t)tp.tv_sec * 1000000000LL) + (int64_t)tp.tv_nsec;
return Val_long(ns);
return Val_long(dune_clock_gettime_ns());
}

#endif
10 changes: 5 additions & 5 deletions otherlibs/stdune/src/wait4_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ void dune_wait4(value v_pid, value flags) {
#include <sys/time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <stdint.h>

#include "dune_clock.h"

#define TAG_WEXITED 0
#define TAG_WSIGNALED 1
#define TAG_WSTOPPED 2
Expand Down Expand Up @@ -68,7 +69,7 @@ value dune_wait4(value v_pid, value flags) {
CAMLlocal2(times, res);

int status, cv_flags;
struct timespec tp;
int64_t time_ns;
cv_flags = caml_convert_flag_list(flags, wait_flag_table);
pid_t pid = Int_val(v_pid);

Expand All @@ -78,7 +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;
clock_gettime(CLOCK_REALTIME, &tp);
time_ns = dune_clock_gettime_ns();
caml_leave_blocking_section();
if (pid == 0) {
CAMLreturn(Val_none);
Expand Down Expand Up @@ -107,8 +108,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));
}
Expand Down
8 changes: 4 additions & 4 deletions src/fsevents/fsevents_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <AvailabilityMacros.h>
#endif

#if defined(__APPLE__) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= 101000

#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
};
Expand Down
Loading