mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
Add isc_time_now_hires function to get current time with high resolution
The current isc_time_now uses CLOCK_REALTIME_COARSE which only updates on a timer tick. This clock is generally fine for millisecond accuracy, but on servers with 100hz clocks, this clock is nowhere near accurate enough for microsecond accuracy. This commit adds a new isc_time_now_hires function that uses CLOCK_REALTIME, which gives the current time, though it is somewhat expensive to call. When microsecond accuracy is required, it may be required to use extra resources for higher accuracy.
This commit is contained in:
parent
bee4ee931f
commit
ebced74b19
@ -340,6 +340,8 @@ mock_assert(const int result, const char *const expression,
|
||||
* Time
|
||||
*/
|
||||
#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
|
||||
#define TIME_NOW_HIRES(tp) \
|
||||
RUNTIME_CHECK(isc_time_now_hires((tp)) == ISC_R_SUCCESS)
|
||||
|
||||
/*%
|
||||
* Alignment
|
||||
|
@ -128,7 +128,7 @@ isc_time_formatISO8601us_test(void **state) {
|
||||
UNUSED(state);
|
||||
|
||||
setenv("TZ", "America/Los_Angeles", 1);
|
||||
result = isc_time_now(&t);
|
||||
result = isc_time_now_hires(&t);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/* check formatting: yyyy-mm-ddThh:mm:ss.ssssssZ */
|
||||
@ -236,7 +236,7 @@ isc_time_formatISO8601Lus_test(void **state) {
|
||||
UNUSED(state);
|
||||
|
||||
setenv("TZ", "America/Los_Angeles", 1);
|
||||
result = isc_time_now(&t);
|
||||
result = isc_time_now_hires(&t);
|
||||
assert_int_equal(result, ISC_R_SUCCESS);
|
||||
|
||||
/* check formatting: yyyy-mm-ddThh:mm:ss.ssssss */
|
||||
|
@ -150,6 +150,26 @@ isc_time_now(isc_time_t *t);
|
||||
* in the current definition of isc_time_t.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_time_now_hires(isc_time_t *t);
|
||||
/*%<
|
||||
* Set 't' to the current absolute time. Uses higher resolution clocks
|
||||
* recommended when microsecond accuracy is required.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 't' is a valid pointer.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Success
|
||||
*\li Unexpected error
|
||||
* Getting the time from the system failed.
|
||||
*\li Out of range
|
||||
* The time from the system is too large to be represented
|
||||
* in the current definition of isc_time_t.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i);
|
||||
/*%<
|
||||
|
@ -33,6 +33,10 @@
|
||||
#define NS_PER_US 1000 /*%< Nanoseconds per microsecond. */
|
||||
#define NS_PER_MS 1000000 /*%< Nanoseconds per millisecond. */
|
||||
|
||||
#if defined(CLOCK_REALTIME)
|
||||
#define CLOCKSOURCE_HIRES CLOCK_REALTIME
|
||||
#endif /* #if defined(CLOCK_REALTIME) */
|
||||
|
||||
#if defined(CLOCK_REALTIME_COARSE)
|
||||
#define CLOCKSOURCE CLOCK_REALTIME_COARSE
|
||||
#elif defined(CLOCK_REALTIME_FAST)
|
||||
@ -41,6 +45,10 @@
|
||||
#define CLOCKSOURCE CLOCK_REALTIME
|
||||
#endif /* if defined(CLOCK_REALTIME_COARSE) */
|
||||
|
||||
#if !defined(CLOCKSOURCE_HIRES)
|
||||
#define CLOCKSOURCE_HIRES CLOCKSOURCE
|
||||
#endif /* #ifndef CLOCKSOURCE_HIRES */
|
||||
|
||||
/*%
|
||||
*** Intervals
|
||||
***/
|
||||
@ -106,14 +114,14 @@ isc_time_isepoch(const isc_time_t *t) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_time_now(isc_time_t *t) {
|
||||
static inline isc_result_t
|
||||
time_now(isc_time_t *t, clockid_t clock) {
|
||||
struct timespec ts;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
REQUIRE(t != NULL);
|
||||
|
||||
if (clock_gettime(CLOCKSOURCE, &ts) == -1) {
|
||||
if (clock_gettime(clock, &ts) == -1) {
|
||||
strerror_r(errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
|
||||
return (ISC_R_UNEXPECTED);
|
||||
@ -138,6 +146,16 @@ isc_time_now(isc_time_t *t) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_time_now_hires(isc_time_t *t) {
|
||||
return time_now(t, CLOCKSOURCE_HIRES);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_time_now(isc_time_t *t) {
|
||||
return time_now(t, CLOCKSOURCE);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) {
|
||||
struct timespec ts;
|
||||
|
@ -164,6 +164,26 @@ isc_time_now(isc_time_t *t);
|
||||
* in the current definition of isc_time_t.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_time_now_hires(isc_time_t *t);
|
||||
/*%<
|
||||
* Set 't' to the current absolute time. Uses higher resolution clocks
|
||||
* recommended when microsecond accuracy is required.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
*\li 't' is a valid pointer.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li Success
|
||||
*\li Unexpected error
|
||||
* Getting the time from the system failed.
|
||||
*\li Out of range
|
||||
* The time from the system is too large to be represented
|
||||
* in the current definition of isc_time_t.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i);
|
||||
/*
|
||||
|
@ -691,6 +691,7 @@ isc_time_isepoch
|
||||
isc_time_microdiff
|
||||
isc_time_nanoseconds
|
||||
isc_time_now
|
||||
isc_time_now_hires
|
||||
isc_time_nowplusinterval
|
||||
isc_time_parsehttptimestamp
|
||||
isc_time_secondsastimet
|
||||
|
@ -124,6 +124,15 @@ isc_time_now(isc_time_t *t) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_time_now_hires(isc_time_t *t) {
|
||||
REQUIRE(t != NULL);
|
||||
|
||||
GetSystemTimePreciseAsFileTime(&t->absolute);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) {
|
||||
ULARGE_INTEGER i1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user