Add os_tick_us() and os_tick_ns() monotonic high-resolution timers

This commit is contained in:
Andrea Mazzoleni 2026-10-02 10:13:35 +02:00
parent 68b94bfdf5
commit a7a85a259c
5 changed files with 58 additions and 16 deletions

View file

@ -71,7 +71,7 @@ AC_HEADER_ASSERT
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([dirent.h stdint.h inttypes.h unistd.h math.h execinfo.h strings.h getopt.h syslog.h grp.h pwd.h io.h alloca.h])
AC_CHECK_HEADERS([sys/file.h sys/sysctl.h sys/ioctl.h sys/time.h sys/types.h sys/mkdev.h sys/sysmacros.h sys/stat.h sys/prctl.h sys/sysinfo.h sys/utsname.h])
AC_CHECK_HEADERS([linux/fs.h linux/btrfs.h linux/fiemap.h mach/mach_time.h])
AC_CHECK_HEADERS([linux/fs.h linux/btrfs.h linux/fiemap.h])
# Check for the close_range(...,CLOSE_RANGE_CLOEXEC)
AC_CHECK_HEADERS([linux/close_range.h])
@ -126,7 +126,6 @@ AC_CHECK_FUNCS([fsync posix_fadvise sync_file_range syncfs])
AC_CHECK_FUNCS([getc_unlocked ferror_unlocked])
AC_CHECK_FUNCS([futimes futimens futimesat localtime_r lutimes utimensat])
AC_CHECK_FUNCS([fstatat flock renameat statx])
AC_CHECK_FUNCS([mach_absolute_time])
AC_CHECK_FUNCS([backtrace backtrace_symbols])
AC_SEARCH_LIBS([clock_gettime], [rt])
AC_CHECK_FUNCS([clock_gettime])

View file

@ -64,6 +64,7 @@ static windows_key_t last_error;
*/
static windows_mutex_t tick_lock;
static uint64_t tick_last;
static uint64_t tick_frequency;
/**
* Mutex for process reference publication, termination, and unpublication.
@ -4498,6 +4499,24 @@ uint64_t os_tick_ms(void)
return GetTickCount64();
}
uint64_t os_tick_us(void)
{
uint64_t ticks = os_tick();
uint64_t sec = ticks / tick_frequency;
uint64_t rem = ticks % tick_frequency;
return sec * 1000000ULL + (rem * 1000000ULL) / tick_frequency;
}
uint64_t os_tick_ns(void)
{
uint64_t ticks = os_tick();
uint64_t sec = ticks / tick_frequency;
uint64_t rem = ticks % tick_frequency;
return sec * 1000000000ULL + (rem * 1000000000ULL) / tick_frequency;
}
int os_usleep(uint64_t usec)
{
while (usec > 0) {
@ -4609,6 +4628,13 @@ void os_init(unsigned opt)
os_exit();
}
LARGE_INTEGER freq;
if (!QueryPerformanceFrequency(&freq) || freq.QuadPart <= 0) {
os_syslog(OS_LVL_CRITICAL, "error calling QueryPerformanceFrequency()");
os_exit();
}
tick_frequency = freq.QuadPart;
if (windows_mutex_init(&exec_mutex, 0) != 0) {
os_syslog(OS_LVL_CRITICAL, "error calling windows_mutex_init()");
os_exit();
@ -4684,6 +4710,7 @@ void os_done(void)
windows_mutex_destroy(&exec_mutex);
windows_mutex_destroy(&tick_lock);
tick_frequency = 0;
/* restore the normal execution level */
SetThreadExecutionState(WIN32_ES_CONTINUOUS);

12
os/os.h
View file

@ -397,6 +397,18 @@ uint64_t os_tick(void);
*/
uint64_t os_tick_ms(void);
/**
* Get the os_tick counter value in microsecond.
* \return Monotonic clock value in microseconds.
*/
uint64_t os_tick_us(void);
/**
* Get the os_tick counter value in nanosecond.
* \return Monotonic clock value in nanoseconds.
*/
uint64_t os_tick_ns(void);
/**
* Get the os_tick counter value in seconds.
* \return Monotonic clock value in seconds.

View file

@ -132,7 +132,6 @@
#include <linux/fiemap.h>
#endif
/**
* Includes some standard headers.
*/
@ -174,10 +173,6 @@
#endif
#endif
#if HAVE_MACH_MACH_TIME_H
#include <mach/mach_time.h>
#endif
#if HAVE_DIRENT_H
#include <dirent.h>
#endif

View file

@ -2217,17 +2217,18 @@ void os_privileges_release(void)
uint64_t os_tick(void)
{
#if HAVE_MACH_ABSOLUTE_TIME
/* for Mac OS X */
return mach_absolute_time();
#elif HAVE_CLOCK_GETTIME && (defined(CLOCK_MONOTONIC) || defined(CLOCK_MONOTONIC_RAW))
/* for Linux */
#if HAVE_CLOCK_GETTIME && (defined(CLOCK_UPTIME_RAW) || defined(CLOCK_MONOTONIC_RAW) || defined(CLOCK_MONOTONIC))
struct timespec tv;
/* nanosecond precision with clock_gettime() */
#if defined(CLOCK_MONOTONIC_RAW)
#if defined(CLOCK_UPTIME_RAW)
/* for macOS (without sleep and without NTP slewing) */
if (clock_gettime(CLOCK_UPTIME_RAW, &tv) != 0) {
#elif defined(CLOCK_MONOTONIC_RAW)
/* for Linux (without sleep and without NTP slewing) */
if (clock_gettime(CLOCK_MONOTONIC_RAW, &tv) != 0) {
#else
/* for other POSIX */
if (clock_gettime(CLOCK_MONOTONIC, &tv) != 0) {
#endif
/* LCOV_EXCL_START */
@ -2247,7 +2248,7 @@ uint64_t os_tick(void)
/* LCOV_EXCL_STOP */
}
return tv.tv_sec * 1000000ULL + tv.tv_usec;
return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000ULL;
#endif
}
@ -2276,6 +2277,16 @@ uint64_t os_tick_ms(void)
#endif
}
uint64_t os_tick_us(void)
{
return os_tick() / 1000;
}
uint64_t os_tick_ns(void)
{
return os_tick();
}
uint64_t os_tick_sec(void)
{
#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
@ -2327,8 +2338,6 @@ int os_usleep(uint64_t usec)
return 0;
}
int os_randomize(void* ptr, size_t size)
{
int f;