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:
Miroslav Lichvar
2016-08-17 16:05:53 +02:00
parent 0899ab52dd
commit d0dfa1de9e
46 changed files with 685 additions and 654 deletions

80
sched.c
View File

@@ -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 */