Skip to content

Commit

Permalink
POSIX: Fix portability issues with clock_gettime (koreader#1360)
Browse files Browse the repository at this point in the history
Fix clockid_t constants on macOS & BSDs

Re: koreader/koreader#7593
  • Loading branch information
NiLuJe authored and roygbyte committed Mar 3, 2022
1 parent e6f6bd7 commit 31b21e9
Showing 1 changed file with 149 additions and 7 deletions.
156 changes: 149 additions & 7 deletions ffi/posix_h.lua
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,6 @@ char *realpath(const char *restrict, char *restrict) __attribute__((nothrow, lea
char *basename(char *) __attribute__((nothrow, leaf));
char *dirname(char *) __attribute__((nothrow, leaf));
typedef int clockid_t;
static const int CLOCK_REALTIME = 0;
static const int CLOCK_REALTIME_COARSE = 5;
static const int CLOCK_MONOTONIC = 1;
static const int CLOCK_MONOTONIC_COARSE = 6;
static const int CLOCK_MONOTONIC_RAW = 4;
static const int CLOCK_BOOTTIME = 7;
static const int CLOCK_TAI = 11;
int clock_getres(clockid_t, struct timespec *) __attribute__((nothrow, leaf));
int clock_gettime(clockid_t, struct timespec *) __attribute__((nothrow, leaf));
int clock_settime(clockid_t, const struct timespec *) __attribute__((nothrow, leaf));
Expand Down Expand Up @@ -202,3 +195,152 @@ if ffi.os == "Linux" then
-- in order to let the dynamic loader figure it out on its own (e.g., multilib).
pcall(ffi.load, "rt.so.1", true)
end

-- The clockid_t constants are not portable :/.
if ffi.os == "Linux" then
ffi.cdef[[
static const int CLOCK_REALTIME = 0;
static const int CLOCK_REALTIME_COARSE = 5;
static const int CLOCK_MONOTONIC = 1;
static const int CLOCK_MONOTONIC_COARSE = 6;
static const int CLOCK_MONOTONIC_RAW = 4;
static const int CLOCK_BOOTTIME = 7;
static const int CLOCK_TAI = 11;
]]
elseif ffi.os == "OSX" then
-- c.f., https://github.com/phracker/MacOSX-SDKs/blob/master/MacOSX10.12.sdk/usr/include/time.h
--[[
typedef enum {
_CLOCK_REALTIME = 0,
_CLOCK_MONOTONIC = 6,
_CLOCK_MONOTONIC_RAW = 4,
_CLOCK_MONOTONIC_RAW_APPROX = 5,
_CLOCK_UPTIME_RAW = 8,
_CLOCK_UPTIME_RAW_APPROX = 9,
_CLOCK_PROCESS_CPUTIME_ID = 12,
_CLOCK_THREAD_CPUTIME_ID = 16
} clockid_t;
--]]
-- Portability notes:
-- Unlike on Linux, MONO ticks during sleep (which is technically the POSIX-compliant behavior).
-- CLOCK_UPTIME_* doesn't.
-- (e.g., macOS UPTIME == Linux MONO, and macOS MONO == Linux BOOTTIME)
-- NOTE: Requires macOS 10.12
ffi.cdef[[
static const int CLOCK_REALTIME = 0;
static const int CLOCK_REALTIME_COARSE = -1;
static const int CLOCK_MONOTONIC = 6;
static const int CLOCK_MONOTONIC_COARSE = 5;
static const int CLOCK_MONOTONIC_RAW = 4;
static const int CLOCK_BOOTTIME = -1;
static const int CLOCK_TAI = -1;
]]
elseif ffi.os == "BSD" then
-- OpenBSD
-- c.f., https://github.com/openbsd/src/blob/master/sys/sys/_time.h
--[[
#define CLOCK_REALTIME 0
#define CLOCK_PROCESS_CPUTIME_ID 2
#define CLOCK_MONOTONIC 3
#define CLOCK_THREAD_CPUTIME_ID 4
#define CLOCK_UPTIME 5
#define CLOCK_BOOTTIME 6
--]]
-- Portability notes:
-- OpenBSD UPTIME == Linux MONOTONIC, OpenBSD BOOTTIME == Linux BOOTTIME
-- (Meaning MONOTONIC starts ticking at an *undefined* positive value).
-- NetBSD
-- c.f., https://anonhg.netbsd.org/src/file/tip/sys/sys/time.h
--[[
#define CLOCK_REALTIME 0
#define CLOCK_VIRTUAL 1
#define CLOCK_PROF 2
#define CLOCK_MONOTONIC 3
#define CLOCK_THREAD_CPUTIME_ID 0x20000000
#define CLOCK_PROCESS_CPUTIME_ID 0x40000000
--]]
-- FreeBSD
-- c.f., https://github.com/freebsd/freebsd-src/blob/main/include/time.h
--[[
#define CLOCK_REALTIME 0
#define CLOCK_VIRTUAL 1
#define CLOCK_PROF 2
#define CLOCK_MONOTONIC 4
#define CLOCK_UPTIME 5 /* FreeBSD-specific. */
#define CLOCK_UPTIME_PRECISE 7 /* FreeBSD-specific. */
#define CLOCK_UPTIME_FAST 8 /* FreeBSD-specific. */
#define CLOCK_REALTIME_PRECISE 9 /* FreeBSD-specific. */
#define CLOCK_REALTIME_FAST 10 /* FreeBSD-specific. */
#define CLOCK_MONOTONIC_PRECISE 11 /* FreeBSD-specific. */
#define CLOCK_MONOTONIC_FAST 12 /* FreeBSD-specific. */
#define CLOCK_SECOND 13 /* FreeBSD-specific. */
#define CLOCK_THREAD_CPUTIME_ID 14
#define CLOCK_PROCESS_CPUTIME_ID 15
--]]
-- Portability notes:
-- FreeBSD UPTIME == Linux MONOTONIC
-- (I assume that, like on OpenBSD, this means MONOTONIC starts ticking at an *undefined* positive value).
-- So, here comes probey-time!
local C = ffi.C
local probe_ts = ffi.new("struct timespec")
if C.clock_getres(15, probe_ts) == 0 then
-- FreeBSD
ffi.cdef[[
static const int CLOCK_REALTIME = 0;
static const int CLOCK_REALTIME_COARSE = 10;
static const int CLOCK_MONOTONIC = 4;
static const int CLOCK_MONOTONIC_COARSE = 12;
static const int CLOCK_MONOTONIC_RAW = 11;
static const int CLOCK_BOOTTIME = -1;
static const int CLOCK_TAI = -1;
]]
elseif C.clock_getres(0x40000000, probe_ts) == 0 then
-- NetBSD
ffi.cdef[[
static const int CLOCK_REALTIME = 0;
static const int CLOCK_REALTIME_COARSE = -1;
static const int CLOCK_MONOTONIC = 3;
static const int CLOCK_MONOTONIC_COARSE = -1;
static const int CLOCK_MONOTONIC_RAW = -1;
static const int CLOCK_BOOTTIME = -1;
static const int CLOCK_TAI = -1;
]]
else
-- OpenBSD
ffi.cdef[[
static const int CLOCK_REALTIME = 0;
static const int CLOCK_REALTIME_COARSE = -1;
static const int CLOCK_MONOTONIC = 3;
static const int CLOCK_MONOTONIC_COARSE = -1;
static const int CLOCK_MONOTONIC_RAW = -1;
static const int CLOCK_BOOTTIME = 6;
static const int CLOCK_TAI = -1;
]]
end
probe_ts = nil --luacheck: ignore
else
-- Assume minimal Linux compat on other OSes.

-- This holds true for Windows via mingw,
-- c.f., https://github.com/mirror/mingw-w64/blob/master/mingw-w64-libraries/winpthreads/include/pthread_time.h
--[[
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 1
#define CLOCK_PROCESS_CPUTIME_ID 2
#define CLOCK_THREAD_CPUTIME_ID 3
--]]
ffi.cdef[[
static const int CLOCK_REALTIME = 0;
static const int CLOCK_REALTIME_COARSE = -1;
static const int CLOCK_MONOTONIC = 1;
static const int CLOCK_MONOTONIC_COARSE = -1;
static const int CLOCK_MONOTONIC_RAW = -1;
static const int CLOCK_BOOTTIME = -1;
static const int CLOCK_TAI = -1;
]]
end

0 comments on commit 31b21e9

Please sign in to comment.