2016-07-08 16:38:59 +02:00
|
|
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
|
|
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
2017-03-15 21:13:17 +01:00
|
|
|
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
2016-07-08 16:38:59 +02:00
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* \file compat_time.c
|
|
|
|
* \brief Portable wrappers for finding out the current time, running
|
|
|
|
* timers, etc.
|
|
|
|
**/
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
#define COMPAT_TIME_PRIVATE
|
2016-07-08 16:38:59 +02:00
|
|
|
#include "compat.h"
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include <winsock2.h>
|
|
|
|
#include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_TYPES_H
|
|
|
|
#include <sys/types.h>
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
#ifdef TOR_UNIT_TESTS
|
|
|
|
#if !defined(HAVE_USLEEP) && defined(HAVE_SYS_SELECT_H)
|
|
|
|
/* as fallback implementation for tor_sleep_msec */
|
|
|
|
#include <sys/select.h>
|
|
|
|
#endif
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(TOR_UNIT_TESTS) */
|
2016-07-08 16:38:59 +02:00
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
#ifdef __APPLE__
|
|
|
|
#include <mach/mach_time.h>
|
|
|
|
#endif
|
|
|
|
|
2016-07-08 16:38:59 +02:00
|
|
|
#include "torlog.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "container.h"
|
|
|
|
|
|
|
|
#ifndef HAVE_GETTIMEOFDAY
|
|
|
|
#ifdef HAVE_FTIME
|
|
|
|
#include <sys/timeb.h>
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2016-07-26 14:22:23 +02:00
|
|
|
#ifdef _WIN32
|
|
|
|
#undef HAVE_CLOCK_GETTIME
|
|
|
|
#endif
|
|
|
|
|
2016-07-08 16:38:59 +02:00
|
|
|
#ifdef TOR_UNIT_TESTS
|
|
|
|
/** Delay for <b>msec</b> milliseconds. Only used in tests. */
|
|
|
|
void
|
|
|
|
tor_sleep_msec(int msec)
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
Sleep(msec);
|
|
|
|
#elif defined(HAVE_USLEEP)
|
|
|
|
sleep(msec / 1000);
|
|
|
|
/* Some usleep()s hate sleeping more than 1 sec */
|
|
|
|
usleep((msec % 1000) * 1000);
|
|
|
|
#elif defined(HAVE_SYS_SELECT_H)
|
|
|
|
struct timeval tv = { msec / 1000, (msec % 1000) * 1000};
|
|
|
|
select(0, NULL, NULL, NULL, &tv);
|
|
|
|
#else
|
|
|
|
sleep(CEIL_DIV(msec, 1000));
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(_WIN32) || ... */
|
2016-07-08 16:38:59 +02:00
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(TOR_UNIT_TESTS) */
|
2016-07-08 16:38:59 +02:00
|
|
|
|
|
|
|
/** Set *timeval to the current time of day. On error, log and terminate.
|
|
|
|
* (Same as gettimeofday(timeval,NULL), but never returns -1.)
|
|
|
|
*/
|
2018-04-17 02:18:40 +02:00
|
|
|
MOCK_IMPL(void,
|
|
|
|
tor_gettimeofday, (struct timeval *timeval))
|
2016-07-08 16:38:59 +02:00
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
/* Epoch bias copied from perl: number of units between windows epoch and
|
|
|
|
* Unix epoch. */
|
|
|
|
#define EPOCH_BIAS U64_LITERAL(116444736000000000)
|
|
|
|
#define UNITS_PER_SEC U64_LITERAL(10000000)
|
|
|
|
#define USEC_PER_SEC U64_LITERAL(1000000)
|
|
|
|
#define UNITS_PER_USEC U64_LITERAL(10)
|
|
|
|
union {
|
|
|
|
uint64_t ft_64;
|
|
|
|
FILETIME ft_ft;
|
|
|
|
} ft;
|
|
|
|
/* number of 100-nsec units since Jan 1, 1601 */
|
|
|
|
GetSystemTimeAsFileTime(&ft.ft_ft);
|
|
|
|
if (ft.ft_64 < EPOCH_BIAS) {
|
|
|
|
/* LCOV_EXCL_START */
|
|
|
|
log_err(LD_GENERAL,"System time is before 1970; failing.");
|
2017-10-19 19:42:28 +02:00
|
|
|
exit(1); // exit ok: system clock is broken.
|
2016-07-08 16:38:59 +02:00
|
|
|
/* LCOV_EXCL_STOP */
|
|
|
|
}
|
|
|
|
ft.ft_64 -= EPOCH_BIAS;
|
|
|
|
timeval->tv_sec = (unsigned) (ft.ft_64 / UNITS_PER_SEC);
|
|
|
|
timeval->tv_usec = (unsigned) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
|
|
|
|
#elif defined(HAVE_GETTIMEOFDAY)
|
|
|
|
if (gettimeofday(timeval, NULL)) {
|
|
|
|
/* LCOV_EXCL_START */
|
|
|
|
log_err(LD_GENERAL,"gettimeofday failed.");
|
|
|
|
/* If gettimeofday dies, we have either given a bad timezone (we didn't),
|
|
|
|
or segfaulted.*/
|
2017-10-19 19:42:28 +02:00
|
|
|
exit(1); // exit ok: gettimeofday failed.
|
2016-07-08 16:38:59 +02:00
|
|
|
/* LCOV_EXCL_STOP */
|
|
|
|
}
|
|
|
|
#elif defined(HAVE_FTIME)
|
|
|
|
struct timeb tb;
|
|
|
|
ftime(&tb);
|
|
|
|
timeval->tv_sec = tb.time;
|
|
|
|
timeval->tv_usec = tb.millitm * 1000;
|
|
|
|
#else
|
|
|
|
#error "No way to get time."
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(_WIN32) || ... */
|
2016-07-08 16:38:59 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
#define ONE_MILLION ((int64_t) (1000 * 1000))
|
|
|
|
#define ONE_BILLION ((int64_t) (1000 * 1000 * 1000))
|
|
|
|
|
|
|
|
/** True iff monotime_init has been called. */
|
|
|
|
static int monotime_initialized = 0;
|
|
|
|
|
2016-07-21 11:04:22 +02:00
|
|
|
static monotime_t initialized_at;
|
|
|
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
|
|
|
static monotime_coarse_t initialized_at_coarse;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef TOR_UNIT_TESTS
|
|
|
|
/** True if we are running unit tests and overriding the current monotonic
|
|
|
|
* time. Note that mocked monotonic time might not be monotonic.
|
|
|
|
*/
|
|
|
|
static int monotime_mocking_enabled = 0;
|
|
|
|
static monotime_t initialized_at_saved;
|
|
|
|
|
|
|
|
static int64_t mock_time_nsec = 0;
|
|
|
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
|
|
|
static int64_t mock_time_nsec_coarse = 0;
|
|
|
|
static monotime_coarse_t initialized_at_coarse_saved;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
|
|
|
monotime_enable_test_mocking(void)
|
|
|
|
{
|
|
|
|
if (BUG(monotime_initialized == 0)) {
|
|
|
|
monotime_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
tor_assert_nonfatal(monotime_mocking_enabled == 0);
|
|
|
|
monotime_mocking_enabled = 1;
|
|
|
|
memcpy(&initialized_at_saved,
|
|
|
|
&initialized_at, sizeof(monotime_t));
|
|
|
|
memset(&initialized_at, 0, sizeof(monotime_t));
|
|
|
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
|
|
|
memcpy(&initialized_at_coarse_saved,
|
|
|
|
&initialized_at_coarse, sizeof(monotime_coarse_t));
|
|
|
|
memset(&initialized_at_coarse, 0, sizeof(monotime_coarse_t));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
monotime_disable_test_mocking(void)
|
|
|
|
{
|
|
|
|
tor_assert_nonfatal(monotime_mocking_enabled == 1);
|
|
|
|
monotime_mocking_enabled = 0;
|
|
|
|
|
|
|
|
memcpy(&initialized_at,
|
|
|
|
&initialized_at_saved, sizeof(monotime_t));
|
|
|
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
|
|
|
memcpy(&initialized_at_coarse,
|
|
|
|
&initialized_at_coarse_saved, sizeof(monotime_coarse_t));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
monotime_set_mock_time_nsec(int64_t nsec)
|
|
|
|
{
|
|
|
|
tor_assert_nonfatal(monotime_mocking_enabled == 1);
|
|
|
|
mock_time_nsec = nsec;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
|
|
|
void
|
|
|
|
monotime_coarse_set_mock_time_nsec(int64_t nsec)
|
|
|
|
{
|
|
|
|
tor_assert_nonfatal(monotime_mocking_enabled == 1);
|
|
|
|
mock_time_nsec_coarse = nsec;
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
|
|
|
|
#endif /* defined(TOR_UNIT_TESTS) */
|
2016-07-21 11:04:22 +02:00
|
|
|
|
2016-07-13 16:18:15 +02:00
|
|
|
/* "ratchet" functions for monotonic time. */
|
|
|
|
|
|
|
|
#if defined(_WIN32) || defined(TOR_UNIT_TESTS)
|
|
|
|
|
|
|
|
/** Protected by lock: last value returned by monotime_get(). */
|
|
|
|
static int64_t last_pctr = 0;
|
|
|
|
/** Protected by lock: offset we must add to monotonic time values. */
|
|
|
|
static int64_t pctr_offset = 0;
|
|
|
|
/* If we are using GetTickCount(), how many times has it rolled over? */
|
|
|
|
static uint32_t rollover_count = 0;
|
|
|
|
/* If we are using GetTickCount(), what's the last value it returned? */
|
|
|
|
static int64_t last_tick_count = 0;
|
|
|
|
|
|
|
|
/** Helper for windows: Called with a sequence of times that are supposed
|
|
|
|
* to be monotonic; increments them as appropriate so that they actually
|
|
|
|
* _are_ monotonic.
|
|
|
|
*
|
|
|
|
* Caller must hold lock. */
|
|
|
|
STATIC int64_t
|
|
|
|
ratchet_performance_counter(int64_t count_raw)
|
|
|
|
{
|
|
|
|
/* must hold lock */
|
|
|
|
const int64_t count_adjusted = count_raw + pctr_offset;
|
|
|
|
|
|
|
|
if (PREDICT_UNLIKELY(count_adjusted < last_pctr)) {
|
|
|
|
/* Monotonicity failed! Pretend no time elapsed. */
|
|
|
|
pctr_offset = last_pctr - count_raw;
|
|
|
|
return last_pctr;
|
|
|
|
} else {
|
|
|
|
last_pctr = count_adjusted;
|
|
|
|
return count_adjusted;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
STATIC int64_t
|
|
|
|
ratchet_coarse_performance_counter(const int64_t count_raw)
|
|
|
|
{
|
|
|
|
int64_t count = count_raw + (((int64_t)rollover_count) << 32);
|
|
|
|
while (PREDICT_UNLIKELY(count < last_tick_count)) {
|
|
|
|
++rollover_count;
|
|
|
|
count = count_raw + (((int64_t)rollover_count) << 32);
|
|
|
|
}
|
|
|
|
last_tick_count = count;
|
|
|
|
return count;
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(_WIN32) || defined(TOR_UNIT_TESTS) */
|
2016-07-13 16:18:15 +02:00
|
|
|
|
|
|
|
#if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS)
|
|
|
|
static struct timeval last_timeofday = { 0, 0 };
|
|
|
|
static struct timeval timeofday_offset = { 0, 0 };
|
|
|
|
|
|
|
|
/** Helper for gettimeofday(): Called with a sequence of times that are
|
|
|
|
* supposed to be monotonic; increments them as appropriate so that they
|
|
|
|
* actually _are_ monotonic.
|
|
|
|
*
|
|
|
|
* Caller must hold lock. */
|
|
|
|
STATIC void
|
|
|
|
ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out)
|
|
|
|
{
|
|
|
|
/* must hold lock */
|
|
|
|
timeradd(timeval_raw, &timeofday_offset, out);
|
2017-08-24 21:26:57 +02:00
|
|
|
if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, OP_LT))) {
|
2016-07-13 16:18:15 +02:00
|
|
|
/* time ran backwards. Instead, declare that no time occurred. */
|
|
|
|
timersub(&last_timeofday, timeval_raw, &timeofday_offset);
|
|
|
|
memcpy(out, &last_timeofday, sizeof(struct timeval));
|
|
|
|
} else {
|
|
|
|
memcpy(&last_timeofday, out, sizeof(struct timeval));
|
|
|
|
}
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) */
|
2016-07-13 16:18:15 +02:00
|
|
|
|
|
|
|
#ifdef TOR_UNIT_TESTS
|
|
|
|
/** For testing: reset all the ratchets */
|
|
|
|
void
|
|
|
|
monotime_reset_ratchets_for_testing(void)
|
|
|
|
{
|
|
|
|
last_pctr = pctr_offset = last_tick_count = 0;
|
|
|
|
rollover_count = 0;
|
|
|
|
memset(&last_timeofday, 0, sizeof(struct timeval));
|
|
|
|
memset(&timeofday_offset, 0, sizeof(struct timeval));
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(TOR_UNIT_TESTS) */
|
2016-07-13 16:18:15 +02:00
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
#ifdef __APPLE__
|
|
|
|
|
|
|
|
/** Initialized on startup: tells is how to convert from ticks to
|
|
|
|
* nanoseconds.
|
|
|
|
*/
|
|
|
|
static struct mach_timebase_info mach_time_info;
|
2017-11-21 18:28:16 +01:00
|
|
|
static int monotime_shift = 0;
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
|
|
|
|
static void
|
|
|
|
monotime_init_internal(void)
|
|
|
|
{
|
|
|
|
tor_assert(!monotime_initialized);
|
|
|
|
int r = mach_timebase_info(&mach_time_info);
|
|
|
|
tor_assert(r == 0);
|
|
|
|
tor_assert(mach_time_info.denom != 0);
|
2017-11-21 18:28:16 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
// approximate only.
|
|
|
|
uint64_t ns_per_tick = mach_time_info.numer / mach_time_info.denom;
|
|
|
|
uint64_t ms_per_tick = ns_per_tick * ONE_MILLION;
|
|
|
|
// requires that tor_log2(0) == 0.
|
|
|
|
monotime_shift = tor_log2(ms_per_tick);
|
|
|
|
}
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set "out" to the most recent monotonic time value
|
|
|
|
*/
|
2016-07-21 10:30:21 +02:00
|
|
|
void
|
|
|
|
monotime_get(monotime_t *out)
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
{
|
2016-07-21 11:04:22 +02:00
|
|
|
#ifdef TOR_UNIT_TESTS
|
|
|
|
if (monotime_mocking_enabled) {
|
|
|
|
out->abstime_ = (mock_time_nsec * mach_time_info.denom)
|
|
|
|
/ mach_time_info.numer;
|
|
|
|
return;
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(TOR_UNIT_TESTS) */
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
out->abstime_ = mach_absolute_time();
|
|
|
|
}
|
|
|
|
|
2017-12-08 15:24:02 +01:00
|
|
|
#if defined(HAVE_MACH_APPROXIMATE_TIME)
|
|
|
|
void
|
|
|
|
monotime_coarse_get(monotime_coarse_t *out)
|
|
|
|
{
|
|
|
|
#ifdef TOR_UNIT_TESTS
|
|
|
|
if (monotime_mocking_enabled) {
|
|
|
|
out->abstime_ = (mock_time_nsec_coarse * mach_time_info.denom)
|
|
|
|
/ mach_time_info.numer;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif /* defined(TOR_UNIT_TESTS) */
|
|
|
|
out->abstime_ = mach_approximate_time();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
/**
|
|
|
|
* Return the number of nanoseconds between <b>start</b> and <b>end</b>.
|
|
|
|
*/
|
|
|
|
int64_t
|
|
|
|
monotime_diff_nsec(const monotime_t *start,
|
|
|
|
const monotime_t *end)
|
|
|
|
{
|
2016-07-26 17:07:53 +02:00
|
|
|
if (BUG(mach_time_info.denom == 0)) {
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
monotime_init();
|
|
|
|
}
|
|
|
|
const int64_t diff_ticks = end->abstime_ - start->abstime_;
|
|
|
|
const int64_t diff_nsec =
|
|
|
|
(diff_ticks * mach_time_info.numer) / mach_time_info.denom;
|
|
|
|
return diff_nsec;
|
|
|
|
}
|
|
|
|
|
2017-11-21 18:28:16 +01:00
|
|
|
uint32_t
|
|
|
|
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
|
|
|
{
|
|
|
|
return (uint32_t)(t->abstime_ >> monotime_shift);
|
|
|
|
}
|
|
|
|
|
2017-12-13 14:28:04 +01:00
|
|
|
int
|
|
|
|
monotime_is_zero(const monotime_t *val)
|
|
|
|
{
|
|
|
|
return val->abstime_ == 0;
|
|
|
|
}
|
|
|
|
|
2017-12-13 14:54:29 +01:00
|
|
|
void
|
|
|
|
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
|
|
|
{
|
|
|
|
const uint64_t nsec = msec * ONE_MILLION;
|
|
|
|
const uint64_t ticks = (nsec * mach_time_info.denom) / mach_time_info.numer;
|
|
|
|
out->abstime_ = val->abstime_ + ticks;
|
|
|
|
}
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
/* end of "__APPLE__" */
|
|
|
|
#elif defined(HAVE_CLOCK_GETTIME)
|
|
|
|
|
2016-12-21 14:17:26 +01:00
|
|
|
#ifdef CLOCK_MONOTONIC_COARSE
|
|
|
|
/**
|
|
|
|
* Which clock should we use for coarse-grained monotonic time? By default
|
|
|
|
* this is CLOCK_MONOTONIC_COARSE, but it might not work -- for example,
|
|
|
|
* if we're compiled with newer Linux headers and then we try to run on
|
|
|
|
* an old Linux kernel. In that case, we will fall back to CLOCK_MONOTONIC.
|
|
|
|
*/
|
|
|
|
static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(CLOCK_MONOTONIC_COARSE) */
|
2016-12-21 14:17:26 +01:00
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
static void
|
|
|
|
monotime_init_internal(void)
|
|
|
|
{
|
2016-12-21 14:17:26 +01:00
|
|
|
#ifdef CLOCK_MONOTONIC_COARSE
|
|
|
|
struct timespec ts;
|
|
|
|
if (clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) < 0) {
|
|
|
|
log_info(LD_GENERAL, "CLOCK_MONOTONIC_COARSE isn't working (%s); "
|
|
|
|
"falling back to CLOCK_MONOTONIC.", strerror(errno));
|
|
|
|
clock_monotonic_coarse = CLOCK_MONOTONIC;
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(CLOCK_MONOTONIC_COARSE) */
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
}
|
|
|
|
|
2016-07-21 10:30:21 +02:00
|
|
|
void
|
|
|
|
monotime_get(monotime_t *out)
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
{
|
2016-07-21 11:04:22 +02:00
|
|
|
#ifdef TOR_UNIT_TESTS
|
|
|
|
if (monotime_mocking_enabled) {
|
2016-07-21 14:05:29 +02:00
|
|
|
out->ts_.tv_sec = (time_t) (mock_time_nsec / ONE_BILLION);
|
|
|
|
out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
|
2016-07-21 11:04:22 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(TOR_UNIT_TESTS) */
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
|
|
|
|
tor_assert(r == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CLOCK_MONOTONIC_COARSE
|
2016-07-21 10:30:21 +02:00
|
|
|
void
|
|
|
|
monotime_coarse_get(monotime_coarse_t *out)
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
{
|
2016-07-21 11:04:22 +02:00
|
|
|
#ifdef TOR_UNIT_TESTS
|
|
|
|
if (monotime_mocking_enabled) {
|
2016-07-21 14:32:15 +02:00
|
|
|
out->ts_.tv_sec = (time_t) (mock_time_nsec_coarse / ONE_BILLION);
|
|
|
|
out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION);
|
2016-07-21 11:04:22 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(TOR_UNIT_TESTS) */
|
2016-12-21 14:17:26 +01:00
|
|
|
int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
|
|
|
|
if (PREDICT_UNLIKELY(r < 0) &&
|
|
|
|
errno == EINVAL &&
|
|
|
|
clock_monotonic_coarse == CLOCK_MONOTONIC_COARSE) {
|
|
|
|
/* We should have caught this at startup in monotime_init_internal!
|
|
|
|
*/
|
|
|
|
log_warn(LD_BUG, "Falling back to non-coarse monotonic time %s initial "
|
|
|
|
"system start?", monotime_initialized?"after":"without");
|
|
|
|
clock_monotonic_coarse = CLOCK_MONOTONIC;
|
|
|
|
r = clock_gettime(clock_monotonic_coarse, &out->ts_);
|
|
|
|
}
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
tor_assert(r == 0);
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(CLOCK_MONOTONIC_COARSE) */
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
|
|
|
|
int64_t
|
|
|
|
monotime_diff_nsec(const monotime_t *start,
|
|
|
|
const monotime_t *end)
|
|
|
|
{
|
|
|
|
const int64_t diff_sec = end->ts_.tv_sec - start->ts_.tv_sec;
|
|
|
|
const int64_t diff_nsec = diff_sec * ONE_BILLION +
|
|
|
|
(end->ts_.tv_nsec - start->ts_.tv_nsec);
|
|
|
|
|
|
|
|
return diff_nsec;
|
|
|
|
}
|
|
|
|
|
2017-11-21 18:28:16 +01:00
|
|
|
/* This value is ONE_BILLION >> 20. */
|
2017-12-06 21:46:54 +01:00
|
|
|
static const uint32_t STAMP_TICKS_PER_SECOND = 953;
|
2017-11-21 18:28:16 +01:00
|
|
|
|
|
|
|
uint32_t
|
|
|
|
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
|
|
|
{
|
|
|
|
uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
|
|
|
|
uint32_t sec = (uint32_t)t->ts_.tv_sec;
|
|
|
|
|
|
|
|
return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
|
|
|
|
}
|
|
|
|
|
2017-12-13 14:28:04 +01:00
|
|
|
int
|
|
|
|
monotime_is_zero(const monotime_t *val)
|
|
|
|
{
|
|
|
|
return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
|
|
|
|
}
|
|
|
|
|
2017-12-13 14:54:29 +01:00
|
|
|
void
|
|
|
|
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
|
|
|
{
|
|
|
|
const uint32_t sec = msec / 1000;
|
|
|
|
const uint32_t msec_remainder = msec % 1000;
|
|
|
|
out->ts_.tv_sec = val->ts_.tv_sec + sec;
|
|
|
|
out->ts_.tv_nsec = val->ts_.tv_nsec + (msec_remainder * ONE_MILLION);
|
|
|
|
if (out->ts_.tv_nsec > ONE_BILLION) {
|
|
|
|
out->ts_.tv_nsec -= ONE_BILLION;
|
|
|
|
out->ts_.tv_sec += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
/* end of "HAVE_CLOCK_GETTIME" */
|
|
|
|
#elif defined (_WIN32)
|
|
|
|
|
Fix an integer overflow related to monotonic time on windows.
To maintain precision, to get nanoseconds, we were multiplying our
tick count by a billion, then dividing by ticks-per-second. But
that apparently isn't such a great idea, since ticks-per-second is
sometimes a billion on its own, so our intermediate result was
giving us attoseconds.
When you're counting in attoseconds, you can only fit about 9
seconds into an int64_t, which is not so great for our purposes.
Instead, we now simplify the 1000000000/1000000000 fraction before
we start messing with nanoseconds. This has potential to mess us
up if some future MS version declares that performance counters will
use 1,000,000,007 units per second, but let's burn that bridge when
we come to it.
2016-07-26 17:23:58 +02:00
|
|
|
/** Result of QueryPerformanceFrequency, in terms needed to
|
|
|
|
* convert ticks to nanoseconds. */
|
|
|
|
static int64_t nsec_per_tick_numer = 1;
|
|
|
|
static int64_t nsec_per_tick_denom = 1;
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
|
|
|
|
/** Lock to protect last_pctr and pctr_offset */
|
|
|
|
static CRITICAL_SECTION monotime_lock;
|
2016-07-13 16:18:15 +02:00
|
|
|
/** Lock to protect rollover_count and last_tick_count */
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
static CRITICAL_SECTION monotime_coarse_lock;
|
|
|
|
|
|
|
|
typedef ULONGLONG (WINAPI *GetTickCount64_fn_t)(void);
|
|
|
|
static GetTickCount64_fn_t GetTickCount64_fn = NULL;
|
|
|
|
|
|
|
|
static void
|
|
|
|
monotime_init_internal(void)
|
|
|
|
{
|
|
|
|
tor_assert(!monotime_initialized);
|
|
|
|
BOOL ok = InitializeCriticalSectionAndSpinCount(&monotime_lock, 200);
|
|
|
|
tor_assert(ok);
|
|
|
|
ok = InitializeCriticalSectionAndSpinCount(&monotime_coarse_lock, 200);
|
|
|
|
tor_assert(ok);
|
|
|
|
LARGE_INTEGER li;
|
|
|
|
ok = QueryPerformanceFrequency(&li);
|
|
|
|
tor_assert(ok);
|
|
|
|
tor_assert(li.QuadPart);
|
Fix an integer overflow related to monotonic time on windows.
To maintain precision, to get nanoseconds, we were multiplying our
tick count by a billion, then dividing by ticks-per-second. But
that apparently isn't such a great idea, since ticks-per-second is
sometimes a billion on its own, so our intermediate result was
giving us attoseconds.
When you're counting in attoseconds, you can only fit about 9
seconds into an int64_t, which is not so great for our purposes.
Instead, we now simplify the 1000000000/1000000000 fraction before
we start messing with nanoseconds. This has potential to mess us
up if some future MS version declares that performance counters will
use 1,000,000,007 units per second, but let's burn that bridge when
we come to it.
2016-07-26 17:23:58 +02:00
|
|
|
|
|
|
|
uint64_t n = ONE_BILLION;
|
|
|
|
uint64_t d = li.QuadPart;
|
|
|
|
/* We need to simplify this or we'll probably overflow the int64. */
|
|
|
|
simplify_fraction64(&n, &d);
|
|
|
|
tor_assert(n <= INT64_MAX);
|
|
|
|
tor_assert(d <= INT64_MAX);
|
|
|
|
|
|
|
|
nsec_per_tick_numer = (int64_t) n;
|
|
|
|
nsec_per_tick_denom = (int64_t) d;
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
last_pctr = 0;
|
|
|
|
pctr_offset = 0;
|
|
|
|
|
|
|
|
HANDLE h = load_windows_system_library(TEXT("kernel32.dll"));
|
|
|
|
if (h) {
|
|
|
|
GetTickCount64_fn = (GetTickCount64_fn_t)
|
|
|
|
GetProcAddress(h, "GetTickCount64");
|
|
|
|
}
|
|
|
|
// FreeLibrary(h) ?
|
|
|
|
}
|
|
|
|
|
2016-07-21 10:30:21 +02:00
|
|
|
void
|
|
|
|
monotime_get(monotime_t *out)
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
{
|
|
|
|
if (BUG(monotime_initialized == 0)) {
|
|
|
|
monotime_init();
|
|
|
|
}
|
|
|
|
|
2016-07-21 11:04:22 +02:00
|
|
|
#ifdef TOR_UNIT_TESTS
|
|
|
|
if (monotime_mocking_enabled) {
|
Fix an integer overflow related to monotonic time on windows.
To maintain precision, to get nanoseconds, we were multiplying our
tick count by a billion, then dividing by ticks-per-second. But
that apparently isn't such a great idea, since ticks-per-second is
sometimes a billion on its own, so our intermediate result was
giving us attoseconds.
When you're counting in attoseconds, you can only fit about 9
seconds into an int64_t, which is not so great for our purposes.
Instead, we now simplify the 1000000000/1000000000 fraction before
we start messing with nanoseconds. This has potential to mess us
up if some future MS version declares that performance counters will
use 1,000,000,007 units per second, but let's burn that bridge when
we come to it.
2016-07-26 17:23:58 +02:00
|
|
|
out->pcount_ = (mock_time_nsec * nsec_per_tick_denom)
|
|
|
|
/ nsec_per_tick_numer;
|
2016-07-21 11:04:22 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(TOR_UNIT_TESTS) */
|
2016-07-21 11:04:22 +02:00
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
/* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
|
|
|
|
|
|
|
|
https://www.python.org/dev/peps/pep-0418/#windows-queryperformancecounter
|
|
|
|
*/
|
|
|
|
|
|
|
|
EnterCriticalSection(&monotime_lock);
|
|
|
|
LARGE_INTEGER res;
|
|
|
|
BOOL ok = QueryPerformanceCounter(&res);
|
|
|
|
tor_assert(ok);
|
|
|
|
const int64_t count_raw = res.QuadPart;
|
|
|
|
out->pcount_ = ratchet_performance_counter(count_raw);
|
|
|
|
LeaveCriticalSection(&monotime_lock);
|
|
|
|
}
|
|
|
|
|
2016-07-21 10:30:21 +02:00
|
|
|
void
|
|
|
|
monotime_coarse_get(monotime_coarse_t *out)
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
{
|
2016-07-21 11:04:22 +02:00
|
|
|
#ifdef TOR_UNIT_TESTS
|
|
|
|
if (monotime_mocking_enabled) {
|
|
|
|
out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
|
|
|
|
return;
|
|
|
|
}
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(TOR_UNIT_TESTS) */
|
2016-07-21 11:04:22 +02:00
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
if (GetTickCount64_fn) {
|
|
|
|
out->tick_count_ = (int64_t)GetTickCount64_fn();
|
|
|
|
} else {
|
|
|
|
EnterCriticalSection(&monotime_coarse_lock);
|
|
|
|
DWORD tick = GetTickCount();
|
|
|
|
out->tick_count_ = ratchet_coarse_performance_counter(tick);
|
|
|
|
LeaveCriticalSection(&monotime_coarse_lock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t
|
|
|
|
monotime_diff_nsec(const monotime_t *start,
|
|
|
|
const monotime_t *end)
|
|
|
|
{
|
|
|
|
if (BUG(monotime_initialized == 0)) {
|
|
|
|
monotime_init();
|
|
|
|
}
|
|
|
|
const int64_t diff_ticks = end->pcount_ - start->pcount_;
|
Fix an integer overflow related to monotonic time on windows.
To maintain precision, to get nanoseconds, we were multiplying our
tick count by a billion, then dividing by ticks-per-second. But
that apparently isn't such a great idea, since ticks-per-second is
sometimes a billion on its own, so our intermediate result was
giving us attoseconds.
When you're counting in attoseconds, you can only fit about 9
seconds into an int64_t, which is not so great for our purposes.
Instead, we now simplify the 1000000000/1000000000 fraction before
we start messing with nanoseconds. This has potential to mess us
up if some future MS version declares that performance counters will
use 1,000,000,007 units per second, but let's burn that bridge when
we come to it.
2016-07-26 17:23:58 +02:00
|
|
|
return (diff_ticks * nsec_per_tick_numer) / nsec_per_tick_denom;
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int64_t
|
|
|
|
monotime_coarse_diff_msec(const monotime_coarse_t *start,
|
|
|
|
const monotime_coarse_t *end)
|
|
|
|
{
|
|
|
|
const int64_t diff_ticks = end->tick_count_ - start->tick_count_;
|
|
|
|
return diff_ticks;
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t
|
|
|
|
monotime_coarse_diff_usec(const monotime_coarse_t *start,
|
|
|
|
const monotime_coarse_t *end)
|
|
|
|
{
|
|
|
|
return monotime_coarse_diff_msec(start, end) * 1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t
|
|
|
|
monotime_coarse_diff_nsec(const monotime_coarse_t *start,
|
|
|
|
const monotime_coarse_t *end)
|
|
|
|
{
|
|
|
|
return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
|
|
|
|
}
|
|
|
|
|
2017-12-06 21:46:54 +01:00
|
|
|
static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
|
2017-11-21 18:28:16 +01:00
|
|
|
|
|
|
|
uint32_t
|
|
|
|
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
|
|
|
{
|
2017-12-07 21:14:49 +01:00
|
|
|
return (uint32_t) t->tick_count_;
|
2017-11-21 18:28:16 +01:00
|
|
|
}
|
|
|
|
|
2017-12-13 14:28:04 +01:00
|
|
|
int
|
|
|
|
monotime_is_zero(const monotime_t *val)
|
|
|
|
{
|
|
|
|
return val->pcount_ == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
monotime_coarse_is_zero(const monotime_coarse_t *val)
|
|
|
|
{
|
|
|
|
return val->tick_count_ == 0;
|
|
|
|
}
|
|
|
|
|
2017-12-13 14:54:29 +01:00
|
|
|
void
|
|
|
|
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
|
|
|
{
|
|
|
|
const uint64_t nsec = msec * ONE_MILLION;
|
|
|
|
const uint64_t ticks = (nsec * nsec_per_tick_denom) / nsec_per_tick_numer;
|
|
|
|
out->pcount_ = val->pcount_ + ticks;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2017-12-20 23:45:59 +01:00
|
|
|
monotime_coarse_add_msec(monotime_coarse_t *out, const monotime_coarse_t *val,
|
|
|
|
uint32_t msec)
|
2017-12-13 14:54:29 +01:00
|
|
|
{
|
|
|
|
out->tick_count_ = val->tick_count_ + msec;
|
|
|
|
}
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
/* end of "_WIN32" */
|
|
|
|
#elif defined(MONOTIME_USING_GETTIMEOFDAY)
|
|
|
|
|
|
|
|
static tor_mutex_t monotime_lock;
|
|
|
|
|
|
|
|
/** Initialize the monotonic timer subsystem. */
|
|
|
|
static void
|
|
|
|
monotime_init_internal(void)
|
|
|
|
{
|
|
|
|
tor_assert(!monotime_initialized);
|
|
|
|
tor_mutex_init(&monotime_lock);
|
|
|
|
}
|
|
|
|
|
2016-07-21 10:30:21 +02:00
|
|
|
void
|
|
|
|
monotime_get(monotime_t *out)
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
{
|
|
|
|
if (BUG(monotime_initialized == 0)) {
|
|
|
|
monotime_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
tor_mutex_acquire(&monotime_lock);
|
|
|
|
struct timeval timeval_raw;
|
|
|
|
tor_gettimeofday(&timeval_raw);
|
|
|
|
ratchet_timeval(&timeval_raw, &out->tv_);
|
|
|
|
tor_mutex_release(&monotime_lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t
|
|
|
|
monotime_diff_nsec(const monotime_t *start,
|
|
|
|
const monotime_t *end)
|
|
|
|
{
|
|
|
|
struct timeval diff;
|
|
|
|
timersub(&end->tv_, &start->tv_, &diff);
|
|
|
|
return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
|
|
|
|
}
|
|
|
|
|
2017-11-21 18:28:16 +01:00
|
|
|
/* This value is ONE_MILLION >> 10. */
|
2017-12-06 21:46:54 +01:00
|
|
|
static const uint32_t STAMP_TICKS_PER_SECOND = 976;
|
2017-11-21 18:28:16 +01:00
|
|
|
|
|
|
|
uint32_t
|
|
|
|
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
|
|
|
{
|
|
|
|
const uint32_t usec = (uint32_t)t->tv_.tv_usec;
|
|
|
|
const uint32_t sec = (uint32_t)t->tv_.tv_sec;
|
|
|
|
return (sec * STAMP_TICKS_PER_SECOND) | (nsec >> 10);
|
|
|
|
}
|
|
|
|
|
2017-12-13 14:28:04 +01:00
|
|
|
int
|
|
|
|
monotime_is_zero(const monotime_t *val)
|
|
|
|
{
|
|
|
|
return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
|
|
|
|
}
|
|
|
|
|
2017-12-13 14:54:29 +01:00
|
|
|
void
|
|
|
|
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
|
|
|
{
|
|
|
|
const uint32_t sec = msec / 1000;
|
|
|
|
const uint32_t msec_remainder = msec % 1000;
|
|
|
|
out->tv_.tv_sec = val->tv_.tv_sec + sec;
|
|
|
|
out->tv_.tv_usec = val->tv_.tv_nsec + (msec_remainder * 1000);
|
|
|
|
if (out->tv_.tv_usec > ONE_MILLION) {
|
|
|
|
out->tv_.tv_usec -= ONE_MILLION;
|
|
|
|
out->tv_.tv_sec += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
/* end of "MONOTIME_USING_GETTIMEOFDAY" */
|
|
|
|
#else
|
|
|
|
#error "No way to implement monotonic timers."
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(__APPLE__) || ... */
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize the monotonic timer subsystem. Must be called before any
|
|
|
|
* monotonic timer functions. This function is idempotent.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
monotime_init(void)
|
|
|
|
{
|
|
|
|
if (!monotime_initialized) {
|
|
|
|
monotime_init_internal();
|
2016-07-21 15:29:56 +02:00
|
|
|
monotime_initialized = 1;
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
monotime_get(&initialized_at);
|
|
|
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
|
|
|
monotime_coarse_get(&initialized_at_coarse);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-13 14:28:04 +01:00
|
|
|
void
|
|
|
|
monotime_zero(monotime_t *out)
|
|
|
|
{
|
|
|
|
memset(out, 0, sizeof(*out));
|
|
|
|
}
|
|
|
|
#ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
|
|
|
|
void
|
|
|
|
monotime_coarse_zero(monotime_coarse_t *out)
|
|
|
|
{
|
|
|
|
memset(out, 0, sizeof(*out));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
int64_t
|
|
|
|
monotime_diff_usec(const monotime_t *start,
|
|
|
|
const monotime_t *end)
|
|
|
|
{
|
|
|
|
const int64_t nsec = monotime_diff_nsec(start, end);
|
|
|
|
return CEIL_DIV(nsec, 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t
|
|
|
|
monotime_diff_msec(const monotime_t *start,
|
|
|
|
const monotime_t *end)
|
|
|
|
{
|
|
|
|
const int64_t nsec = monotime_diff_nsec(start, end);
|
|
|
|
return CEIL_DIV(nsec, ONE_MILLION);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
monotime_absolute_nsec(void)
|
|
|
|
{
|
|
|
|
monotime_t now;
|
2016-07-19 11:36:43 +02:00
|
|
|
if (BUG(monotime_initialized == 0)) {
|
|
|
|
monotime_init();
|
|
|
|
}
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
monotime_get(&now);
|
|
|
|
return monotime_diff_nsec(&initialized_at, &now);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
monotime_absolute_usec(void)
|
|
|
|
{
|
|
|
|
return monotime_absolute_nsec() / 1000;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
monotime_absolute_msec(void)
|
|
|
|
{
|
|
|
|
return monotime_absolute_nsec() / ONE_MILLION;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef MONOTIME_COARSE_FN_IS_DIFFERENT
|
|
|
|
uint64_t
|
|
|
|
monotime_coarse_absolute_nsec(void)
|
|
|
|
{
|
2016-07-19 11:36:43 +02:00
|
|
|
if (BUG(monotime_initialized == 0)) {
|
|
|
|
monotime_init();
|
|
|
|
}
|
|
|
|
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
monotime_coarse_t now;
|
|
|
|
monotime_coarse_get(&now);
|
|
|
|
return monotime_coarse_diff_nsec(&initialized_at_coarse, &now);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
monotime_coarse_absolute_usec(void)
|
|
|
|
{
|
2016-07-13 16:18:15 +02:00
|
|
|
return monotime_coarse_absolute_nsec() / 1000;
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
monotime_coarse_absolute_msec(void)
|
|
|
|
{
|
2016-07-13 16:18:15 +02:00
|
|
|
return monotime_coarse_absolute_nsec() / ONE_MILLION;
|
Basic portable monotonic timer implementation
This code uses QueryPerformanceCounter() [**] on Windows,
mach_absolute_time() on OSX, clock_gettime() where available, and
gettimeofday() [*] elsewhere.
Timer types are stored in an opaque OS-specific format; the only
supported operation is to compute the difference between two timers.
[*] As you know, gettimeofday() isn't monotonic, so we include
a simple ratchet function to ensure that it only moves forward.
[**] As you may not know, QueryPerformanceCounter() isn't actually
always as monotonic as you might like it to be, so we ratchet that
one too.
We also include a "coarse monotonic timer" for cases where we don't
actually need high-resolution time. This is GetTickCount{,64}() on
Windows, clock_gettime(CLOCK_MONOTONIC_COARSE) on Linux, and falls
back to regular monotonic time elsewhere.
2016-07-08 18:53:51 +02:00
|
|
|
}
|
2017-11-21 18:28:16 +01:00
|
|
|
#else
|
2018-01-24 09:55:15 +01:00
|
|
|
#define initialized_at_coarse initialized_at
|
2017-09-15 22:24:44 +02:00
|
|
|
#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
|
2016-07-29 07:05:12 +02:00
|
|
|
|
2017-11-21 18:28:16 +01:00
|
|
|
/**
|
|
|
|
* Return the current time "stamp" as described by monotime_coarse_to_stamp.
|
|
|
|
*/
|
|
|
|
uint32_t
|
|
|
|
monotime_coarse_get_stamp(void)
|
|
|
|
{
|
|
|
|
monotime_coarse_t now;
|
|
|
|
monotime_coarse_get(&now);
|
|
|
|
return monotime_coarse_to_stamp(&now);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
uint64_t
|
|
|
|
monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
|
|
|
|
{
|
|
|
|
/* Recover as much precision as we can. */
|
|
|
|
uint64_t abstime_diff = (units << monotime_shift);
|
|
|
|
return (abstime_diff * mach_time_info.numer) /
|
|
|
|
(mach_time_info.denom * ONE_MILLION);
|
|
|
|
}
|
2018-04-10 16:47:11 +02:00
|
|
|
uint64_t
|
|
|
|
monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
|
|
|
|
{
|
|
|
|
uint64_t abstime_val =
|
|
|
|
(((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
|
|
|
|
mach_time_info.numer;
|
|
|
|
return abstime_val >> monotime_shift;
|
|
|
|
}
|
2017-11-21 18:28:16 +01:00
|
|
|
#else
|
|
|
|
uint64_t
|
|
|
|
monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
|
|
|
|
{
|
|
|
|
return (units * 1000) / STAMP_TICKS_PER_SECOND;
|
|
|
|
}
|
2018-04-10 16:47:11 +02:00
|
|
|
uint64_t
|
|
|
|
monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
|
|
|
|
{
|
|
|
|
return (msec * STAMP_TICKS_PER_SECOND) / 1000;
|
|
|
|
}
|
2017-11-21 18:28:16 +01:00
|
|
|
#endif
|
|
|
|
|