Last active
April 17, 2021 21:18
-
-
Save truemedian/38ca62704cfd26829ae32a013cb51653 to your computer and use it in GitHub Desktop.
Windows / Posix compatible clock_gettime(REALTIME) ffi bindings.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local ffi = require 'ffi' | |
local bit = require 'bit' | |
local clock_gettime | |
if ffi.os == 'Windows' then | |
local UNIX_TIME_START = 0x019DB1DED53E8000LL | |
local TICKS_PER_SECOND = 10000000LL | |
ffi.cdef [[ | |
typedef struct _FILETIME { | |
int dwLowDateTime; | |
int dwHighDateTime; | |
} FILETIME, *PFILETIME, *LPFILETIME; | |
void GetSystemTimeAsFileTime( | |
LPFILETIME lpSystemTimeAsFileTime | |
); | |
]] | |
function clock_gettime() | |
local struct = assert(ffi.new('FILETIME[1]')) | |
ffi.C.GetSystemTimeAsFileTime(struct[0]) | |
local low = ffi.cast('int64_t', struct[0].dwLowDateTime) | |
local high = ffi.cast('int64_t', struct[0].dwHighDateTime) | |
local windows_time = bit.lshift(high, 32) + low | |
local unix_time = windows_time - UNIX_TIME_START | |
return tonumber(unix_time / TICKS_PER_SECOND) + tonumber(unix_time % TICKS_PER_SECOND) / | |
tonumber(TICKS_PER_SECOND) | |
end | |
else | |
local CLOCK_REALTIME = 0 | |
local NS_PER_SEC = 1e9 | |
ffi.cdef [[ | |
typedef struct timespec { | |
long tv_sec; | |
long tv_nsec; | |
} accurate_realtime; | |
int clock_gettime( int clk_id, struct timespec *tp ); | |
]] | |
function clock_gettime() | |
local struct = assert(ffi.new('accurate_realtime[1]')) | |
ffi.C.clock_gettime(CLOCK_REALTIME, struct) | |
local sec = tonumber(struct[0].tv_sec) | |
local nsec = tonumber(struct[0].tv_nsec) | |
return sec + nsec / NS_PER_SEC | |
end | |
end | |
return clock_gettime |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment