mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-04 14:25:06 -05:00
adopt struct timespec
Replace struct timeval with struct timespec as the main data type for timestamps. This will allow the NTP code to work with timestamps in nanosecond resolution.
This commit is contained in:
80
sched.c
80
sched.c
@@ -62,7 +62,7 @@ typedef struct {
|
||||
static ARR_Instance file_handlers;
|
||||
|
||||
/* Timestamp when last select() returned */
|
||||
static struct timeval last_select_ts, last_select_ts_raw;
|
||||
static struct timespec last_select_ts, last_select_ts_raw;
|
||||
static double last_select_ts_err;
|
||||
|
||||
/* ================================================== */
|
||||
@@ -73,7 +73,7 @@ typedef struct _TimerQueueEntry
|
||||
{
|
||||
struct _TimerQueueEntry *next; /* Forward and back links in the list */
|
||||
struct _TimerQueueEntry *prev;
|
||||
struct timeval tv; /* Local system time at which the
|
||||
struct timespec ts; /* Local system time at which the
|
||||
timeout is to expire. Clearly this
|
||||
must be in terms of what the
|
||||
operating system thinks of as
|
||||
@@ -101,7 +101,7 @@ static SCH_TimeoutID next_tqe_id;
|
||||
static TimerQueueEntry *tqe_free_list = NULL;
|
||||
|
||||
/* Timestamp when was last timeout dispatched for each class */
|
||||
static struct timeval last_class_dispatch[SCH_NumberOfClasses];
|
||||
static struct timespec last_class_dispatch[SCH_NumberOfClasses];
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
@@ -110,8 +110,8 @@ static int need_to_exit;
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
handle_slew(struct timeval *raw,
|
||||
struct timeval *cooked,
|
||||
handle_slew(struct timespec *raw,
|
||||
struct timespec *cooked,
|
||||
double dfreq,
|
||||
double doffset,
|
||||
LCL_ChangeType change_type,
|
||||
@@ -231,7 +231,7 @@ SCH_SetFileHandlerEvents(int fd, int events)
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
SCH_GetLastEventTime(struct timeval *cooked, double *err, struct timeval *raw)
|
||||
SCH_GetLastEventTime(struct timespec *cooked, double *err, struct timespec *raw)
|
||||
{
|
||||
if (cooked) {
|
||||
*cooked = last_select_ts;
|
||||
@@ -298,7 +298,7 @@ try_again:
|
||||
/* ================================================== */
|
||||
|
||||
SCH_TimeoutID
|
||||
SCH_AddTimeout(struct timeval *tv, SCH_TimeoutHandler handler, SCH_ArbitraryArgument arg)
|
||||
SCH_AddTimeout(struct timespec *ts, SCH_TimeoutHandler handler, SCH_ArbitraryArgument arg)
|
||||
{
|
||||
TimerQueueEntry *new_tqe;
|
||||
TimerQueueEntry *ptr;
|
||||
@@ -310,12 +310,12 @@ SCH_AddTimeout(struct timeval *tv, SCH_TimeoutHandler handler, SCH_ArbitraryArgu
|
||||
new_tqe->id = get_new_tqe_id();
|
||||
new_tqe->handler = handler;
|
||||
new_tqe->arg = arg;
|
||||
new_tqe->tv = *tv;
|
||||
new_tqe->ts = *ts;
|
||||
new_tqe->class = SCH_ReservedTimeoutValue;
|
||||
|
||||
/* Now work out where to insert the new entry in the list */
|
||||
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
||||
if (UTI_CompareTimevals(&new_tqe->tv, &ptr->tv) == -1) {
|
||||
if (UTI_CompareTimespecs(&new_tqe->ts, &ptr->ts) == -1) {
|
||||
/* If the new entry comes before the current pointer location in
|
||||
the list, we want to insert the new entry just before ptr. */
|
||||
break;
|
||||
@@ -342,14 +342,14 @@ SCH_AddTimeout(struct timeval *tv, SCH_TimeoutHandler handler, SCH_ArbitraryArgu
|
||||
SCH_TimeoutID
|
||||
SCH_AddTimeoutByDelay(double delay, SCH_TimeoutHandler handler, SCH_ArbitraryArgument arg)
|
||||
{
|
||||
struct timeval now, then;
|
||||
struct timespec now, then;
|
||||
|
||||
assert(initialised);
|
||||
assert(delay >= 0.0);
|
||||
|
||||
LCL_ReadRawTime(&now);
|
||||
UTI_AddDoubleToTimeval(&now, delay, &then);
|
||||
if (UTI_CompareTimevals(&now, &then) > 0) {
|
||||
UTI_AddDoubleToTimespec(&now, delay, &then);
|
||||
if (UTI_CompareTimespecs(&now, &then) > 0) {
|
||||
LOG_FATAL(LOGF_Scheduler, "Timeout overflow");
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||
{
|
||||
TimerQueueEntry *new_tqe;
|
||||
TimerQueueEntry *ptr;
|
||||
struct timeval now;
|
||||
struct timespec now;
|
||||
double diff, r;
|
||||
double new_min_delay;
|
||||
|
||||
@@ -387,7 +387,7 @@ SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||
new_min_delay = min_delay;
|
||||
|
||||
/* Check the separation from the last dispatched timeout */
|
||||
UTI_DiffTimevalsToDouble(&diff, &now, &last_class_dispatch[class]);
|
||||
UTI_DiffTimespecsToDouble(&diff, &now, &last_class_dispatch[class]);
|
||||
if (diff < separation && diff >= 0.0 && diff + new_min_delay < separation) {
|
||||
new_min_delay = separation - diff;
|
||||
}
|
||||
@@ -396,7 +396,7 @@ SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||
if necessary to keep at least the separation away */
|
||||
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
||||
if (ptr->class == class) {
|
||||
UTI_DiffTimevalsToDouble(&diff, &ptr->tv, &now);
|
||||
UTI_DiffTimespecsToDouble(&diff, &ptr->ts, &now);
|
||||
if (new_min_delay > diff) {
|
||||
if (new_min_delay - diff < separation) {
|
||||
new_min_delay = diff + separation;
|
||||
@@ -410,7 +410,7 @@ SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||
}
|
||||
|
||||
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
||||
UTI_DiffTimevalsToDouble(&diff, &ptr->tv, &now);
|
||||
UTI_DiffTimespecsToDouble(&diff, &ptr->ts, &now);
|
||||
if (diff > new_min_delay) {
|
||||
break;
|
||||
}
|
||||
@@ -422,7 +422,7 @@ SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||
new_tqe->id = get_new_tqe_id();
|
||||
new_tqe->handler = handler;
|
||||
new_tqe->arg = arg;
|
||||
UTI_AddDoubleToTimeval(&now, new_min_delay, &new_tqe->tv);
|
||||
UTI_AddDoubleToTimespec(&now, new_min_delay, &new_tqe->ts);
|
||||
new_tqe->class = class;
|
||||
|
||||
new_tqe->next = ptr;
|
||||
@@ -476,7 +476,7 @@ SCH_RemoveTimeout(SCH_TimeoutID id)
|
||||
completed). */
|
||||
|
||||
static void
|
||||
dispatch_timeouts(struct timeval *now) {
|
||||
dispatch_timeouts(struct timespec *now) {
|
||||
TimerQueueEntry *ptr;
|
||||
SCH_TimeoutHandler handler;
|
||||
SCH_ArbitraryArgument arg;
|
||||
@@ -486,7 +486,7 @@ dispatch_timeouts(struct timeval *now) {
|
||||
LCL_ReadRawTime(now);
|
||||
|
||||
if (!(n_timer_queue_entries > 0 &&
|
||||
UTI_CompareTimevals(now, &(timer_queue.next->tv)) >= 0)) {
|
||||
UTI_CompareTimespecs(now, &timer_queue.next->ts) >= 0)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -547,8 +547,8 @@ dispatch_filehandlers(int nfd, fd_set *read_fds, fd_set *write_fds)
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
handle_slew(struct timeval *raw,
|
||||
struct timeval *cooked,
|
||||
handle_slew(struct timespec *raw,
|
||||
struct timespec *cooked,
|
||||
double dfreq,
|
||||
double doffset,
|
||||
LCL_ChangeType change_type,
|
||||
@@ -566,17 +566,17 @@ handle_slew(struct timeval *raw,
|
||||
/* If a step change occurs, just shift all raw time stamps by the offset */
|
||||
|
||||
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
||||
UTI_AddDoubleToTimeval(&ptr->tv, -doffset, &ptr->tv);
|
||||
UTI_AddDoubleToTimespec(&ptr->ts, -doffset, &ptr->ts);
|
||||
}
|
||||
|
||||
for (i = 0; i < SCH_NumberOfClasses; i++) {
|
||||
UTI_AddDoubleToTimeval(&last_class_dispatch[i], -doffset, &last_class_dispatch[i]);
|
||||
UTI_AddDoubleToTimespec(&last_class_dispatch[i], -doffset, &last_class_dispatch[i]);
|
||||
}
|
||||
|
||||
UTI_AddDoubleToTimeval(&last_select_ts_raw, -doffset, &last_select_ts_raw);
|
||||
UTI_AddDoubleToTimespec(&last_select_ts_raw, -doffset, &last_select_ts_raw);
|
||||
}
|
||||
|
||||
UTI_AdjustTimeval(&last_select_ts, cooked, &last_select_ts, &delta, dfreq, doffset);
|
||||
UTI_AdjustTimespec(&last_select_ts, cooked, &last_select_ts, &delta, dfreq, doffset);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
@@ -626,31 +626,33 @@ fill_fd_sets(fd_set **read_fds, fd_set **write_fds)
|
||||
#define JUMP_DETECT_THRESHOLD 10
|
||||
|
||||
static int
|
||||
check_current_time(struct timeval *prev_raw, struct timeval *raw, int timeout,
|
||||
check_current_time(struct timespec *prev_raw, struct timespec *raw, int timeout,
|
||||
struct timeval *orig_select_tv,
|
||||
struct timeval *rem_select_tv)
|
||||
{
|
||||
struct timeval elapsed_min, elapsed_max;
|
||||
struct timespec elapsed_min, elapsed_max, orig_select_ts, rem_select_ts;
|
||||
double step, elapsed;
|
||||
|
||||
UTI_TimevalToTimespec(orig_select_tv, &orig_select_ts);
|
||||
|
||||
/* Get an estimate of the time spent waiting in the select() call. On some
|
||||
systems (e.g. Linux) the timeout timeval is modified to return the
|
||||
remaining time, use that information. */
|
||||
if (timeout) {
|
||||
elapsed_max = elapsed_min = *orig_select_tv;
|
||||
elapsed_max = elapsed_min = orig_select_ts;
|
||||
} else if (rem_select_tv && rem_select_tv->tv_sec >= 0 &&
|
||||
rem_select_tv->tv_sec <= orig_select_tv->tv_sec &&
|
||||
(rem_select_tv->tv_sec != orig_select_tv->tv_sec ||
|
||||
rem_select_tv->tv_usec != orig_select_tv->tv_usec)) {
|
||||
UTI_DiffTimevals(&elapsed_min, orig_select_tv, rem_select_tv);
|
||||
UTI_TimevalToTimespec(rem_select_tv, &rem_select_ts);
|
||||
UTI_DiffTimespecs(&elapsed_min, &orig_select_ts, &rem_select_ts);
|
||||
elapsed_max = elapsed_min;
|
||||
} else {
|
||||
if (rem_select_tv)
|
||||
elapsed_max = *orig_select_tv;
|
||||
elapsed_max = orig_select_ts;
|
||||
else
|
||||
UTI_DiffTimevals(&elapsed_max, raw, prev_raw);
|
||||
elapsed_min.tv_sec = 0;
|
||||
elapsed_min.tv_usec = 0;
|
||||
UTI_DiffTimespecs(&elapsed_max, raw, prev_raw);
|
||||
UTI_ZeroTimespec(&elapsed_min);
|
||||
}
|
||||
|
||||
if (last_select_ts_raw.tv_sec + elapsed_min.tv_sec >
|
||||
@@ -663,8 +665,8 @@ check_current_time(struct timeval *prev_raw, struct timeval *raw, int timeout,
|
||||
return 1;
|
||||
}
|
||||
|
||||
UTI_DiffTimevalsToDouble(&step, &last_select_ts_raw, raw);
|
||||
UTI_TimevalToDouble(&elapsed_min, &elapsed);
|
||||
UTI_DiffTimespecsToDouble(&step, &last_select_ts_raw, raw);
|
||||
UTI_TimespecToDouble(&elapsed_min, &elapsed);
|
||||
step += elapsed;
|
||||
|
||||
/* Cooked time may no longer be valid after dispatching the handlers */
|
||||
@@ -681,7 +683,7 @@ SCH_MainLoop(void)
|
||||
fd_set read_fds, write_fds, *p_read_fds, *p_write_fds;
|
||||
int status, errsv;
|
||||
struct timeval tv, saved_tv, *ptv;
|
||||
struct timeval now, saved_now, cooked;
|
||||
struct timespec ts, now, saved_now, cooked;
|
||||
double err;
|
||||
|
||||
assert(initialised);
|
||||
@@ -697,12 +699,12 @@ SCH_MainLoop(void)
|
||||
|
||||
/* Check whether there is a timeout and set it up */
|
||||
if (n_timer_queue_entries > 0) {
|
||||
UTI_DiffTimespecs(&ts, &timer_queue.next->ts, &now);
|
||||
assert(ts.tv_sec > 0 || ts.tv_nsec > 0);
|
||||
|
||||
UTI_DiffTimevals(&tv, &(timer_queue.next->tv), &now);
|
||||
UTI_TimespecToTimeval(&ts, &tv);
|
||||
ptv = &tv;
|
||||
assert(tv.tv_sec > 0 || tv.tv_usec > 0);
|
||||
saved_tv = tv;
|
||||
|
||||
} else {
|
||||
ptv = NULL;
|
||||
/* This is needed to fix a compiler warning */
|
||||
|
||||
Reference in New Issue
Block a user