diff options
author | David Allsopp <david.allsopp@metastack.com> | 2022-06-29 12:56:36 +0100 |
---|---|---|
committer | David Allsopp <david.allsopp@metastack.com> | 2022-10-14 14:12:00 +0100 |
commit | 4154c1079fc5d899338db0a69cbe36ec8350e978 (patch) | |
tree | 3f600ff648ef259eeb64810e9aadb105f04ee484 /otherlibs/unix | |
parent | 7ca38217b4fed7ab6f65b04114eb1d061e83cead (diff) | |
download | ocaml-4154c1079fc5d899338db0a69cbe36ec8350e978.tar.gz |
Use aligned 64-bit arithmetic for FILETIME
It is not safe/performant to cast a FILETIME to a 64-bit integer,
however in virtually all instances what is wanted is the 64-bit integer.
Use a union to allow punning between a FILETIME and ULONGLONG, avoiding
copying.
Diffstat (limited to 'otherlibs/unix')
-rw-r--r-- | otherlibs/unix/gettimeofday_win32.c | 12 | ||||
-rw-r--r-- | otherlibs/unix/times_win32.c | 22 | ||||
-rw-r--r-- | otherlibs/unix/utimes_win32.c | 24 |
3 files changed, 23 insertions, 35 deletions
diff --git a/otherlibs/unix/gettimeofday_win32.c b/otherlibs/unix/gettimeofday_win32.c index ca6c91a4d3..4ba4a8a6a6 100644 --- a/otherlibs/unix/gettimeofday_win32.c +++ b/otherlibs/unix/gettimeofday_win32.c @@ -17,17 +17,17 @@ #include <caml/alloc.h> #include <time.h> +#define CAML_INTERNALS +#include <caml/winsupport.h> + #include "unixsupport.h" double caml_unix_gettimeofday_unboxed(value unit) { - FILETIME ft; + CAML_ULONGLONG_FILETIME utime; double tm; - ULARGE_INTEGER utime; - GetSystemTimeAsFileTime(&ft); - utime.LowPart = ft.dwLowDateTime; - utime.HighPart = ft.dwHighDateTime; - tm = utime.QuadPart - CAML_NT_EPOCH_100ns_TICKS; + GetSystemTimeAsFileTime(&utime.ft); + tm = utime.ul - CAML_NT_EPOCH_100ns_TICKS; return (tm * 1e-7); /* tm is in 100ns */ } diff --git a/otherlibs/unix/times_win32.c b/otherlibs/unix/times_win32.c index 37fdef9d09..9666a95b1d 100644 --- a/otherlibs/unix/times_win32.c +++ b/otherlibs/unix/times_win32.c @@ -18,29 +18,23 @@ #include "unixsupport.h" #include <windows.h> - -static double to_sec(FILETIME ft) { - ULARGE_INTEGER tmp = {{ft.dwLowDateTime, ft.dwHighDateTime}}; - - /* convert to seconds: - GetProcessTimes returns number of 100-nanosecond intervals */ - return tmp.QuadPart / 1e7; -} - +#define CAML_INTERNALS +#include <caml/winsupport.h> value caml_unix_times(value unit) { value res; - FILETIME creation, exit, stime, utime; + FILETIME _creation, _exit; + CAML_ULONGLONG_FILETIME stime, utime; - if (!(GetProcessTimes(GetCurrentProcess(), &creation, &exit, &stime, - &utime))) { + if (!(GetProcessTimes(GetCurrentProcess(), &_creation, &_exit, + &stime.ft, &utime.ft))) { caml_win32_maperr(GetLastError()); caml_uerror("times", Nothing); } res = caml_alloc_small(4 * Double_wosize, Double_array_tag); - Store_double_field(res, 0, to_sec(utime)); - Store_double_field(res, 1, to_sec(stime)); + Store_double_field(res, 0, (double)(utime.ul / 1e7)); + Store_double_field(res, 1, (double)(stime.ul / 1e7)); Store_double_field(res, 2, 0); Store_double_field(res, 3, 0); return res; diff --git a/otherlibs/unix/utimes_win32.c b/otherlibs/unix/utimes_win32.c index f1543eea79..940f25c62a 100644 --- a/otherlibs/unix/utimes_win32.c +++ b/otherlibs/unix/utimes_win32.c @@ -20,25 +20,17 @@ #include <caml/memory.h> #include <caml/signals.h> #include <caml/osdeps.h> +#include <caml/winsupport.h> #include "unixsupport.h" #include <windows.h> -static void convert_time(double unixTime, FILETIME* ft) -{ - ULARGE_INTEGER u; - u.QuadPart = - (ULONGLONG)(unixTime * 10000000.0) + CAML_NT_EPOCH_100ns_TICKS; - ft->dwLowDateTime = u.LowPart; - ft->dwHighDateTime = u.HighPart; -} - CAMLprim value caml_unix_utimes(value path, value atime, value mtime) { CAMLparam3(path, atime, mtime); WCHAR *wpath; HANDLE hFile; - FILETIME lastAccessTime, lastModificationTime; + CAML_ULONGLONG_FILETIME lastAccessTime, lastModificationTime; SYSTEMTIME systemTime; double at, mt; BOOL res; @@ -63,14 +55,16 @@ CAMLprim value caml_unix_utimes(value path, value atime, value mtime) } if (at == 0.0 && mt == 0.0) { GetSystemTime(&systemTime); - SystemTimeToFileTime(&systemTime, &lastAccessTime); - memcpy(&lastModificationTime, &lastAccessTime, sizeof(FILETIME)); + SystemTimeToFileTime(&systemTime, &lastAccessTime.ft); + lastModificationTime.ul = lastAccessTime.ul; } else { - convert_time(at, &lastAccessTime); - convert_time(mt, &lastModificationTime); + lastAccessTime.ul = + (ULONGLONG)(at * 10000000.0) + CAML_NT_EPOCH_100ns_TICKS; + lastModificationTime.ul = + (ULONGLONG)(mt * 10000000.0) + CAML_NT_EPOCH_100ns_TICKS; } caml_enter_blocking_section(); - res = SetFileTime(hFile, NULL, &lastAccessTime, &lastModificationTime); + res = SetFileTime(hFile, NULL, &lastAccessTime.ft, &lastModificationTime.ft); caml_leave_blocking_section(); if (res == 0) { caml_win32_maperr(GetLastError()); |