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

14
candm.h
View file

@ -96,12 +96,12 @@
#define REQ_LOCAL2 56
#define N_REQUEST_TYPES 57
/* Structure used to exchange timevals independent on size of time_t */
/* Structure used to exchange timespecs independent of time_t size */
typedef struct {
uint32_t tv_sec_high;
uint32_t tv_sec_low;
uint32_t tv_nsec;
} Timeval;
} Timespec;
/* This is used in tv_sec_high for 32-bit timestamps */
#define TV_NOHIGHSEC 0x7fffffff
@ -200,12 +200,12 @@ typedef struct {
} REQ_Modify_Makestep;
typedef struct {
Timeval ts;
Timespec ts;
int32_t EOR;
} REQ_Logon;
typedef struct {
Timeval ts;
Timespec ts;
int32_t EOR;
} REQ_Settime;
@ -512,7 +512,7 @@ typedef struct {
IPAddr ip_addr;
uint16_t stratum;
uint16_t leap_status;
Timeval ref_time;
Timespec ref_time;
Float current_correction;
Float last_offset;
Float rms_offset;
@ -540,7 +540,7 @@ typedef struct {
} RPY_Sourcestats;
typedef struct {
Timeval ref_time;
Timespec ref_time;
uint16_t n_samples;
uint16_t n_runs;
uint32_t span_seconds;
@ -590,7 +590,7 @@ typedef struct {
#define MAX_MANUAL_LIST_SAMPLES 16
typedef struct {
Timeval when;
Timespec when;
Float slewed_offset;
Float orig_offset;
Float residual;

View file

@ -1685,7 +1685,7 @@ print_report(const char *format, ...)
unsigned long long_uinteger;
unsigned int uinteger;
int integer;
struct timeval *tv;
struct timespec *ts;
struct tm *tm;
double dbl;
@ -1800,9 +1800,9 @@ print_report(const char *format, ...)
else
print_nanoseconds(dbl);
break;
case 'T': /* timeval as date and time in UTC */
tv = va_arg(ap, struct timeval *);
tm = gmtime(&tv->tv_sec);
case 'T': /* timespec as date and time in UTC */
ts = va_arg(ap, struct timespec *);
tm = gmtime(&ts->tv_sec);
if (!tm)
break;
strftime(buf, sizeof (buf), "%a %b %d %T %Y", tm);
@ -1812,9 +1812,9 @@ print_report(const char *format, ...)
long_uinteger = va_arg(ap, unsigned long);
printf("%*lu", width, long_uinteger);
break;
case 'V': /* timeval as seconds since epoch */
tv = va_arg(ap, struct timeval *);
printf("%s", UTI_TimevalToString(tv));
case 'V': /* timespec as seconds since epoch */
ts = va_arg(ap, struct timespec *);
printf("%s", UTI_TimespecToString(ts));
break;
/* Classic printf specifiers */
@ -2081,7 +2081,7 @@ process_cmd_tracking(char *line)
IPAddr ip_addr;
uint32_t ref_id;
char name[50];
struct timeval ref_time;
struct timespec ref_time;
const char *leap_status;
request.command = htons(REQ_TRACKING);
@ -2112,7 +2112,7 @@ process_cmd_tracking(char *line)
break;
}
UTI_TimevalNetworkToHost(&reply.data.tracking.ref_time, &ref_time);
UTI_TimespecNetworkToHost(&reply.data.tracking.ref_time, &ref_time);
print_report("Reference ID : %R (%s)\n"
"Stratum : %u\n"
@ -2230,13 +2230,13 @@ process_cmd_rtcreport(char *line)
{
CMD_Request request;
CMD_Reply reply;
struct timeval ref_time;
struct timespec ref_time;
request.command = htons(REQ_RTCREPORT);
if (!request_reply(&request, &reply, RPY_RTC, 0))
return 0;
UTI_TimevalNetworkToHost(&reply.data.rtc.ref_time, &ref_time);
UTI_TimespecNetworkToHost(&reply.data.rtc.ref_time, &ref_time);
print_report("RTC ref time (UTC) : %T\n"
"Number of samples : %u\n"
@ -2328,7 +2328,7 @@ process_cmd_manual_list(const char *line)
CMD_Reply reply;
uint32_t i, n_samples;
RPY_ManualListSample *sample;
struct timeval when;
struct timespec when;
request.command = htons(REQ_MANUAL_LIST);
if (!request_reply(&request, &reply, RPY_MANUAL_LIST, 0))
@ -2341,7 +2341,7 @@ process_cmd_manual_list(const char *line)
for (i = 0; i < n_samples; i++) {
sample = &reply.data.manual_list.samples[i];
UTI_TimevalNetworkToHost(&sample->when, &when);
UTI_TimespecNetworkToHost(&sample->when, &when);
print_report("%2d %s %10.2f %10.2f %10.2f\n",
i, UTI_TimeToLogForm(when.tv_sec),
@ -2376,7 +2376,7 @@ process_cmd_manual_delete(CMD_Request *msg, const char *line)
static int
process_cmd_settime(char *line)
{
struct timeval ts;
struct timespec ts;
time_t now, new_time;
CMD_Request request;
CMD_Reply reply;
@ -2391,8 +2391,8 @@ process_cmd_settime(char *line)
printf("510 - Could not parse date string\n");
} else {
ts.tv_sec = new_time;
ts.tv_usec = 0;
UTI_TimevalHostToNetwork(&ts, &request.data.settime.ts);
ts.tv_nsec = 0;
UTI_TimespecHostToNetwork(&ts, &request.data.settime.ts);
request.command = htons(REQ_SETTIME);
if (request_reply(&request, &reply, RPY_MANUAL_TIMESTAMP, 1)) {
offset_cs = ntohl(reply.data.manual_timestamp.centiseconds);

View file

@ -336,23 +336,24 @@ CLG_Finalise(void)
/* ================================================== */
static uint32_t
get_ts_from_timeval(struct timeval *tv)
get_ts_from_timespec(struct timespec *ts)
{
uint32_t sec = tv->tv_sec, usec = tv->tv_usec;
uint32_t sec = ts->tv_sec, nsec = ts->tv_nsec;
return sec << TS_FRAC | (4295U * usec - (usec >> 5)) >> (32 - TS_FRAC);
/* This is fast and accurate enough */
return sec << TS_FRAC | (140740U * (nsec >> 15)) >> (32 - TS_FRAC);
}
/* ================================================== */
static void
update_record(struct timeval *now, uint32_t *last_hit, uint32_t *hits,
update_record(struct timespec *now, uint32_t *last_hit, uint32_t *hits,
uint16_t *tokens, uint32_t max_tokens, int token_shift, int8_t *rate)
{
uint32_t interval, now_ts, prev_hit, new_tokens;
int interval2;
now_ts = get_ts_from_timeval(now);
now_ts = get_ts_from_timespec(now);
prev_hit = *last_hit;
*last_hit = now_ts;
@ -405,7 +406,7 @@ get_index(Record *record)
/* ================================================== */
int
CLG_LogNTPAccess(IPAddr *client, struct timeval *now)
CLG_LogNTPAccess(IPAddr *client, struct timespec *now)
{
Record *record;
@ -435,7 +436,7 @@ CLG_LogNTPAccess(IPAddr *client, struct timeval *now)
/* ================================================== */
int
CLG_LogCommandAccess(IPAddr *client, struct timeval *now)
CLG_LogCommandAccess(IPAddr *client, struct timespec *now)
{
Record *record;
@ -586,7 +587,7 @@ static uint32_t get_last_ago(uint32_t x, uint32_t y)
/* ================================================== */
int
CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, struct timeval *now)
CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, struct timespec *now)
{
Record *record;
uint32_t now_ts;
@ -599,7 +600,7 @@ CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *repo
if (record->ip_addr.family == IPADDR_UNSPEC)
return 0;
now_ts = get_ts_from_timeval(now);
now_ts = get_ts_from_timespec(now);
report->ip_addr = record->ip_addr;
report->ntp_hits = record->ntp_hits;

View file

@ -33,15 +33,15 @@
extern void CLG_Initialise(void);
extern void CLG_Finalise(void);
extern int CLG_LogNTPAccess(IPAddr *client, struct timeval *now);
extern int CLG_LogCommandAccess(IPAddr *client, struct timeval *now);
extern int CLG_LogNTPAccess(IPAddr *client, struct timespec *now);
extern int CLG_LogCommandAccess(IPAddr *client, struct timespec *now);
extern int CLG_LimitNTPResponseRate(int index);
extern int CLG_LimitCommandResponseRate(int index);
/* And some reporting functions, for use by chronyc. */
extern int CLG_GetNumberOfIndices(void);
extern int CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, struct timeval *now);
extern int CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, struct timespec *now);
extern void CLG_GetServerStatsReport(RPT_ServerStatsReport *report);
#endif /* GOT_CLIENTLOG_H */

View file

@ -564,10 +564,10 @@ handle_modify_makestep(CMD_Request *rx_message, CMD_Reply *tx_message)
static void
handle_settime(CMD_Request *rx_message, CMD_Reply *tx_message)
{
struct timeval ts;
struct timespec ts;
long offset_cs;
double dfreq_ppm, new_afreq_ppm;
UTI_TimevalNetworkToHost(&rx_message->data.settime.ts, &ts);
UTI_TimespecNetworkToHost(&rx_message->data.settime.ts, &ts);
if (!MNL_IsEnabled()) {
tx_message->status = htons(STT_NOTENABLED);
} else if (MNL_AcceptTimestamp(&ts, &offset_cs, &dfreq_ppm, &new_afreq_ppm)) {
@ -634,7 +634,7 @@ static void
handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
{
RPT_SourceReport report;
struct timeval now_corr;
struct timespec now_corr;
/* Get data */
SCH_GetLastEventTime(&now_corr, NULL, NULL);
@ -898,7 +898,7 @@ handle_tracking(CMD_Request *rx_message, CMD_Reply *tx_message)
UTI_IPHostToNetwork(&rpt.ip_addr, &tx_message->data.tracking.ip_addr);
tx_message->data.tracking.stratum = htons(rpt.stratum);
tx_message->data.tracking.leap_status = htons(rpt.leap_status);
UTI_TimevalHostToNetwork(&rpt.ref_time, &tx_message->data.tracking.ref_time);
UTI_TimespecHostToNetwork(&rpt.ref_time, &tx_message->data.tracking.ref_time);
tx_message->data.tracking.current_correction = UTI_FloatHostToNetwork(rpt.current_correction);
tx_message->data.tracking.last_offset = UTI_FloatHostToNetwork(rpt.last_offset);
tx_message->data.tracking.rms_offset = UTI_FloatHostToNetwork(rpt.rms_offset);
@ -916,7 +916,7 @@ static void
handle_smoothing(CMD_Request *rx_message, CMD_Reply *tx_message)
{
RPT_SmoothingReport report;
struct timeval now;
struct timespec now;
SCH_GetLastEventTime(&now, NULL, NULL);
@ -940,7 +940,7 @@ handle_smoothing(CMD_Request *rx_message, CMD_Reply *tx_message)
static void
handle_smoothtime(CMD_Request *rx_message, CMD_Reply *tx_message)
{
struct timeval now;
struct timespec now;
int option;
if (!SMT_IsEnabled()) {
@ -971,7 +971,7 @@ handle_sourcestats(CMD_Request *rx_message, CMD_Reply *tx_message)
{
int status;
RPT_SourcestatsReport report;
struct timeval now_corr;
struct timespec now_corr;
SCH_GetLastEventTime(&now_corr, NULL, NULL);
status = SRC_ReportSourcestats(ntohl(rx_message->data.sourcestats.index),
@ -1004,7 +1004,7 @@ handle_rtcreport(CMD_Request *rx_message, CMD_Reply *tx_message)
status = RTC_GetReport(&report);
if (status) {
tx_message->reply = htons(RPY_RTC);
UTI_TimevalHostToNetwork(&report.ref_time, &tx_message->data.rtc.ref_time);
UTI_TimespecHostToNetwork(&report.ref_time, &tx_message->data.rtc.ref_time);
tx_message->data.rtc.n_samples = htons(report.n_samples);
tx_message->data.rtc.n_runs = htons(report.n_runs);
tx_message->data.rtc.span_seconds = htonl(report.span_seconds);
@ -1041,7 +1041,7 @@ handle_client_accesses_by_index(CMD_Request *rx_message, CMD_Reply *tx_message)
RPY_ClientAccesses_Client *client;
int n_indices;
uint32_t i, j, req_first_index, req_n_clients;
struct timeval now;
struct timespec now;
SCH_GetLastEventTime(&now, NULL, NULL);
@ -1100,7 +1100,7 @@ handle_manual_list(CMD_Request *rx_message, CMD_Reply *tx_message)
tx_message->data.manual_list.n_samples = htonl(n_samples);
for (i=0; i<n_samples; i++) {
sample = &tx_message->data.manual_list.samples[i];
UTI_TimevalHostToNetwork(&report[i].when, &sample->when);
UTI_TimespecHostToNetwork(&report[i].when, &sample->when);
sample->slewed_offset = UTI_FloatHostToNetwork(report[i].slewed_offset);
sample->orig_offset = UTI_FloatHostToNetwork(report[i].orig_offset);
sample->residual = UTI_FloatHostToNetwork(report[i].residual);
@ -1199,7 +1199,7 @@ read_from_cmd_socket(int sock_fd, int event, void *anything)
socklen_t from_length;
IPAddr remote_ip;
unsigned short remote_port, rx_command;
struct timeval now, cooked_now;
struct timespec now, cooked_now;
rx_message_length = sizeof(rx_message);
from_length = sizeof(where_from);

19
keys.c
View file

@ -103,9 +103,9 @@ static int
determine_hash_delay(uint32_t key_id)
{
NTP_Packet pkt;
struct timeval before, after;
unsigned long usecs, min_usecs=0;
int i;
struct timespec before, after;
double diff, min_diff;
int i, nsecs;
for (i = 0; i < 10; i++) {
LCL_ReadRawTime(&before);
@ -113,19 +113,18 @@ determine_hash_delay(uint32_t key_id)
(unsigned char *)&pkt.auth_data, sizeof (pkt.auth_data));
LCL_ReadRawTime(&after);
usecs = (after.tv_sec - before.tv_sec) * 1000000 + (after.tv_usec - before.tv_usec);
UTI_DiffTimespecsToDouble(&diff, &after, &before);
if (i == 0 || usecs < min_usecs) {
min_usecs = usecs;
}
if (i == 0 || min_diff > diff)
min_diff = diff;
}
/* Add on a bit extra to allow for copying, conversions etc */
min_usecs += min_usecs >> 4;
nsecs = 1.0625e9 * min_diff;
DEBUG_LOG(LOGF_Keys, "authentication delay for key %"PRIu32": %ld useconds", key_id, min_usecs);
DEBUG_LOG(LOGF_Keys, "authentication delay for key %"PRIu32": %d nsecs", key_id, nsecs);
return min_usecs;
return nsecs;
}
/* ================================================== */

75
local.c
View file

@ -106,37 +106,42 @@ static double max_clock_error;
under 1s of busy waiting. */
#define NITERS 100
#define NSEC_PER_SEC 1000000000
static void
calculate_sys_precision(void)
{
struct timeval tv, old_tv;
int dusec, best_dusec;
int iters;
struct timespec ts, old_ts;
int iters, diff, best;
gettimeofday(&old_tv, NULL);
best_dusec = 1000000; /* Assume we must be better than a second */
LCL_ReadRawTime(&old_ts);
/* Assume we must be better than a second */
best = NSEC_PER_SEC;
iters = 0;
do {
gettimeofday(&tv, NULL);
dusec = 1000000*(tv.tv_sec - old_tv.tv_sec) + (tv.tv_usec - old_tv.tv_usec);
old_tv = tv;
if (dusec > 0) {
if (dusec < best_dusec) {
best_dusec = dusec;
}
LCL_ReadRawTime(&ts);
diff = NSEC_PER_SEC * (ts.tv_sec - old_ts.tv_sec) + (ts.tv_nsec - old_ts.tv_nsec);
old_ts = ts;
if (diff > 0) {
if (diff < best)
best = diff;
iters++;
}
} while (iters < NITERS);
assert(best_dusec > 0);
assert(best > 0);
precision_quantum = best_dusec * 1.0e-6;
precision_quantum = 1.0e-9 * best;
/* Get rounded log2 value of the measured precision */
precision_log = 0;
while (best_dusec < 707107) {
while (best < 707106781) {
precision_log--;
best_dusec *= 2;
best *= 2;
}
DEBUG_LOG(LOGF_Local, "Clock precision %.9f (%d)", precision_quantum, precision_log);
@ -278,7 +283,7 @@ LCL_IsFirstParameterChangeHandler(LCL_ParameterChangeHandler handler)
/* ================================================== */
static void
invoke_parameter_change_handlers(struct timeval *raw, struct timeval *cooked,
invoke_parameter_change_handlers(struct timespec *raw, struct timespec *cooked,
double dfreq, double doffset,
LCL_ChangeType change_type)
{
@ -349,19 +354,23 @@ void LCL_RemoveDispersionNotifyHandler(LCL_DispersionNotifyHandler handler, void
I can't think of a Unix system where it would not be */
void
LCL_ReadRawTime(struct timeval *result)
LCL_ReadRawTime(struct timespec *ts)
{
if (gettimeofday(result, NULL) < 0) {
struct timeval tv;
if (gettimeofday(&tv, NULL) < 0) {
LOG_FATAL(LOGF_Local, "gettimeofday() failed");
}
UTI_TimevalToTimespec(&tv, ts);
}
/* ================================================== */
void
LCL_ReadCookedTime(struct timeval *result, double *err)
LCL_ReadCookedTime(struct timespec *result, double *err)
{
struct timeval raw;
struct timespec raw;
LCL_ReadRawTime(&raw);
LCL_CookTime(&raw, result, err);
@ -370,18 +379,18 @@ LCL_ReadCookedTime(struct timeval *result, double *err)
/* ================================================== */
void
LCL_CookTime(struct timeval *raw, struct timeval *cooked, double *err)
LCL_CookTime(struct timespec *raw, struct timespec *cooked, double *err)
{
double correction;
LCL_GetOffsetCorrection(raw, &correction, err);
UTI_AddDoubleToTimeval(raw, correction, cooked);
UTI_AddDoubleToTimespec(raw, correction, cooked);
}
/* ================================================== */
void
LCL_GetOffsetCorrection(struct timeval *raw, double *correction, double *err)
LCL_GetOffsetCorrection(struct timespec *raw, double *correction, double *err)
{
/* Call system specific driver to get correction */
(*drv_offset_convert)(raw, correction, err);
@ -421,7 +430,7 @@ clamp_freq(double freq)
/* ================================================== */
static int
check_offset(struct timeval *now, double offset)
check_offset(struct timespec *now, double offset)
{
/* Check if the time will be still sane with accumulated offset */
if (UTI_IsTimeOffsetSane(now, -offset))
@ -439,7 +448,7 @@ check_offset(struct timeval *now, double offset)
void
LCL_SetAbsoluteFrequency(double afreq_ppm)
{
struct timeval raw, cooked;
struct timespec raw, cooked;
double dfreq;
afreq_ppm = clamp_freq(afreq_ppm);
@ -470,7 +479,7 @@ LCL_SetAbsoluteFrequency(double afreq_ppm)
void
LCL_AccumulateDeltaFrequency(double dfreq)
{
struct timeval raw, cooked;
struct timespec raw, cooked;
double old_freq_ppm;
old_freq_ppm = current_freq_ppm;
@ -499,7 +508,7 @@ LCL_AccumulateDeltaFrequency(double dfreq)
void
LCL_AccumulateOffset(double offset, double corr_rate)
{
struct timeval raw, cooked;
struct timespec raw, cooked;
/* In this case, the cooked time to be passed to the notify clients
has to be the cooked time BEFORE the change was made */
@ -521,7 +530,7 @@ LCL_AccumulateOffset(double offset, double corr_rate)
int
LCL_ApplyStepOffset(double offset)
{
struct timeval raw, cooked;
struct timespec raw, cooked;
/* In this case, the cooked time to be passed to the notify clients
has to be the cooked time BEFORE the change was made */
@ -549,7 +558,7 @@ LCL_ApplyStepOffset(double offset)
/* ================================================== */
void
LCL_NotifyExternalTimeStep(struct timeval *raw, struct timeval *cooked,
LCL_NotifyExternalTimeStep(struct timespec *raw, struct timespec *cooked,
double offset, double dispersion)
{
/* Dispatch to all handlers */
@ -563,7 +572,7 @@ LCL_NotifyExternalTimeStep(struct timeval *raw, struct timeval *cooked,
void
LCL_NotifyLeap(int leap)
{
struct timeval raw, cooked;
struct timespec raw, cooked;
LCL_ReadRawTime(&raw);
LCL_CookTime(&raw, &cooked, NULL);
@ -580,7 +589,7 @@ LCL_NotifyLeap(int leap)
void
LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset, double corr_rate)
{
struct timeval raw, cooked;
struct timespec raw, cooked;
double old_freq_ppm;
LCL_ReadRawTime(&raw);
@ -657,7 +666,7 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq,
int
LCL_MakeStep(void)
{
struct timeval raw;
struct timespec raw;
double correction;
LCL_ReadRawTime(&raw);

12
local.h
View file

@ -33,7 +33,7 @@
/* Read the system clock. This is analogous to gettimeofday(),
but with the timezone information ignored */
extern void LCL_ReadRawTime(struct timeval *);
extern void LCL_ReadRawTime(struct timespec *ts);
/* Read the system clock, corrected according to all accumulated
drifts and uncompensated offsets.
@ -44,15 +44,15 @@ extern void LCL_ReadRawTime(struct timeval *);
adjtime()-like interface to correct offsets, and to adjust the
frequency), we must correct the raw time to get this value */
extern void LCL_ReadCookedTime(struct timeval *t, double *err);
extern void LCL_ReadCookedTime(struct timespec *ts, double *err);
/* Convert raw time to cooked. */
extern void LCL_CookTime(struct timeval *raw, struct timeval *cooked, double *err);
extern void LCL_CookTime(struct timespec *raw, struct timespec *cooked, double *err);
/* Read the current offset between the system clock and true time
(i.e. 'cooked' - 'raw') (in seconds). */
extern void LCL_GetOffsetCorrection(struct timeval *raw, double *correction, double *err);
extern void LCL_GetOffsetCorrection(struct timespec *raw, double *correction, double *err);
/* Type of routines that may be invoked as callbacks when there is a
change to the frequency or offset.
@ -79,7 +79,7 @@ typedef enum {
} LCL_ChangeType;
typedef void (*LCL_ParameterChangeHandler)
(struct timeval *raw, struct timeval *cooked,
(struct timespec *raw, struct timespec *cooked,
double dfreq,
double doffset,
LCL_ChangeType change_type,
@ -163,7 +163,7 @@ extern int LCL_ApplyStepOffset(double offset);
/* Routine to invoke notify handlers on an unexpected time jump
in system clock */
extern void LCL_NotifyExternalTimeStep(struct timeval *raw, struct timeval *cooked,
extern void LCL_NotifyExternalTimeStep(struct timespec *raw, struct timespec *cooked,
double offset, double dispersion);
/* Routine to invoke notify handlers on leap second when the system clock

View file

@ -52,7 +52,7 @@ typedef int (*lcl_ApplyStepOffsetDriver)(double offset);
/* System driver to convert a raw time to an adjusted (cooked) time.
The number of seconds returned in 'corr' have to be added to the
raw time to get the corrected time */
typedef void (*lcl_OffsetCorrectionDriver)(struct timeval *raw, double *corr, double *err);
typedef void (*lcl_OffsetCorrectionDriver)(struct timespec *raw, double *corr, double *err);
/* System driver to schedule leap second */
typedef void (*lcl_SetLeapDriver)(int leap);

View file

@ -47,7 +47,7 @@ static int enabled = 0;
/* More recent samples at highest indices */
typedef struct {
struct timeval when; /* This is our 'cooked' time */
struct timespec when; /* This is our 'cooked' time */
double orig_offset; /*+ Not modified by slew samples */
double offset; /*+ if we are fast of the supplied reference */
double residual; /*+ regression residual (sign convention given by
@ -64,8 +64,8 @@ static int n_samples;
/* ================================================== */
static void
slew_samples(struct timeval *raw,
struct timeval *cooked,
slew_samples(struct timespec *raw,
struct timespec *cooked,
double dfreq,
double doffset,
LCL_ChangeType change_type,
@ -97,7 +97,7 @@ MNL_Finalise(void)
/* ================================================== */
static void
estimate_and_set_system(struct timeval *now, int offset_provided, double offset, long *offset_cs, double *dfreq_ppm, double *new_afreq_ppm)
estimate_and_set_system(struct timespec *now, int offset_provided, double offset, long *offset_cs, double *dfreq_ppm, double *new_afreq_ppm)
{
double agos[MAX_SAMPLES], offsets[MAX_SAMPLES];
double b0, b1;
@ -110,7 +110,7 @@ estimate_and_set_system(struct timeval *now, int offset_provided, double offset,
if (n_samples > 1) {
for (i=0; i<n_samples; i++) {
UTI_DiffTimevalsToDouble(&agos[i], &samples[n_samples-1].when, &samples[i].when);
UTI_DiffTimespecsToDouble(&agos[i], &samples[n_samples - 1].when, &samples[i].when);
offsets[i] = samples[i].offset;
}
@ -173,9 +173,9 @@ estimate_and_set_system(struct timeval *now, int offset_provided, double offset,
/* ================================================== */
int
MNL_AcceptTimestamp(struct timeval *ts, long *offset_cs, double *dfreq_ppm, double *new_afreq_ppm)
MNL_AcceptTimestamp(struct timespec *ts, long *offset_cs, double *dfreq_ppm, double *new_afreq_ppm)
{
struct timeval now;
struct timespec now;
double offset, diff;
int i;
@ -189,12 +189,12 @@ MNL_AcceptTimestamp(struct timeval *ts, long *offset_cs, double *dfreq_ppm, doub
return 0;
if (n_samples) {
UTI_DiffTimevalsToDouble(&diff, &now, &samples[n_samples - 1].when);
UTI_DiffTimespecsToDouble(&diff, &now, &samples[n_samples - 1].when);
if (diff < MIN_SAMPLE_SEPARATION)
return 0;
}
UTI_DiffTimevalsToDouble(&offset, &now, ts);
UTI_DiffTimespecsToDouble(&offset, &now, ts);
/* Check if buffer full up */
if (n_samples == MAX_SAMPLES) {
@ -224,8 +224,8 @@ MNL_AcceptTimestamp(struct timeval *ts, long *offset_cs, double *dfreq_ppm, doub
/* ================================================== */
static void
slew_samples(struct timeval *raw,
struct timeval *cooked,
slew_samples(struct timespec *raw,
struct timespec *cooked,
double dfreq,
double doffset,
LCL_ChangeType change_type,
@ -239,7 +239,7 @@ slew_samples(struct timeval *raw,
}
for (i=0; i<n_samples; i++) {
UTI_AdjustTimeval(&samples[i].when, cooked, &samples[i].when, &delta_time,
UTI_AdjustTimespec(&samples[i].when, cooked, &samples[i].when, &delta_time,
dfreq, doffset);
samples[i].offset += delta_time;
}
@ -309,7 +309,7 @@ int
MNL_DeleteSample(int index)
{
int i;
struct timeval now;
struct timespec now;
if ((index < 0) || (index >= n_samples)) {
return 0;

View file

@ -33,7 +33,7 @@
extern void MNL_Initialise(void);
extern void MNL_Finalise(void);
extern int MNL_AcceptTimestamp(struct timeval *ts, long *offset_cs, double *dfreq_ppm, double *new_afreq_ppm);
extern int MNL_AcceptTimestamp(struct timespec *ts, long *offset_cs, double *dfreq_ppm, double *new_afreq_ppm);
extern void MNL_Enable(void);
extern void MNL_Disable(void);

View file

@ -154,18 +154,18 @@ struct NCR_Instance_Record {
parameters for the current reference. (It must be stored
relative to local time to permit frequency and offset adjustments
to be made when we trim the local clock). */
struct timeval local_rx;
struct timespec local_rx;
/* Local timestamp when we last transmitted a packet to the source.
We store two versions. The first is in NTP format, and is used
to validate the next received packet from the source.
Additionally, this is corrected to bring it into line with the
current reference. The second is in timeval format, and is kept
current reference. The second is in timespec format, and is kept
relative to the local clock. We modify this in accordance with
local clock frequency/offset changes, and use this for computing
statistics about the source when a return packet arrives. */
NTP_int64 local_ntp_tx;
struct timeval local_tx;
struct timespec local_tx;
/* The instance record in the main source management module. This
performs the statistical analysis on the samples we generate */
@ -285,30 +285,30 @@ do_size_checks(void)
static void
do_time_checks(void)
{
struct timeval now;
struct timespec now;
time_t warning_advance = 3600 * 24 * 365 * 10; /* 10 years */
#ifdef HAVE_LONG_TIME_T
/* Check that time before NTP_ERA_SPLIT underflows correctly */
struct timeval tv1 = {NTP_ERA_SPLIT, 1}, tv2 = {NTP_ERA_SPLIT - 1, 1};
NTP_int64 ntv1, ntv2;
struct timespec ts1 = {NTP_ERA_SPLIT, 1}, ts2 = {NTP_ERA_SPLIT - 1, 1};
NTP_int64 nts1, nts2;
int r;
UTI_TimevalToInt64(&tv1, &ntv1, NULL);
UTI_TimevalToInt64(&tv2, &ntv2, NULL);
UTI_Int64ToTimeval(&ntv1, &tv1);
UTI_Int64ToTimeval(&ntv2, &tv2);
UTI_TimespecToInt64(&ts1, &nts1, NULL);
UTI_TimespecToInt64(&ts2, &nts2, NULL);
UTI_Int64ToTimespec(&nts1, &ts1);
UTI_Int64ToTimespec(&nts2, &ts2);
r = tv1.tv_sec == NTP_ERA_SPLIT &&
tv1.tv_sec + (1ULL << 32) - 1 == tv2.tv_sec;
r = ts1.tv_sec == NTP_ERA_SPLIT &&
ts1.tv_sec + (1ULL << 32) - 1 == ts2.tv_sec;
assert(r);
LCL_ReadRawTime(&now);
if (tv2.tv_sec - now.tv_sec < warning_advance)
if (ts2.tv_sec - now.tv_sec < warning_advance)
LOG(LOGS_WARN, LOGF_NtpCore, "Assumed NTP time ends at %s!",
UTI_TimeToLogForm(tv2.tv_sec));
UTI_TimeToLogForm(ts2.tv_sec));
#else
LCL_ReadRawTime(&now);
if (now.tv_sec > 0x7fffffff - warning_advance)
@ -385,7 +385,7 @@ static void
start_initial_timeout(NCR_Instance inst)
{
double delay, last_tx;
struct timeval now;
struct timespec now;
if (!inst->tx_timeout_id) {
/* This will be the first transmission after mode change */
@ -398,7 +398,7 @@ start_initial_timeout(NCR_Instance inst)
the interval between packets at least as long as the current polling
interval */
SCH_GetLastEventTime(&now, NULL, NULL);
UTI_DiffTimevalsToDouble(&last_tx, &now, &inst->local_tx);
UTI_DiffTimespecsToDouble(&last_tx, &now, &inst->local_tx);
if (last_tx < 0.0)
last_tx = 0.0;
delay = get_transmit_delay(inst, 0, 0.0) - last_tx;
@ -528,8 +528,7 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar
result->tx_suspended = 1;
result->opmode = params->online ? MD_ONLINE : MD_OFFLINE;
result->local_poll = result->minpoll;
result->local_tx.tv_sec = 0;
result->local_tx.tv_usec = 0;
UTI_ZeroTimespec(&result->local_tx);
NCR_ResetInstance(result);
@ -585,10 +584,9 @@ NCR_ResetInstance(NCR_Instance instance)
instance->remote_orig.hi = 0;
instance->remote_orig.lo = 0;
instance->local_rx.tv_sec = 0;
instance->local_rx.tv_usec = 0;
instance->local_ntp_tx.hi = 0;
instance->local_ntp_tx.lo = 0;
UTI_ZeroTimespec(&instance->local_rx);
if (instance->local_poll != instance->minpoll) {
instance->local_poll = instance->minpoll;
@ -796,8 +794,8 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
int auth_mode, /* The authentication mode */
uint32_t key_id, /* The authentication key ID */
NTP_int64 *orig_ts, /* Originate timestamp (from received packet) */
struct timeval *local_rx, /* Local time request packet was received */
struct timeval *local_tx, /* RESULT : Time this reply
struct timespec *local_rx, /* Local time request packet was received */
struct timespec *local_tx, /* RESULT : Time this reply
is sent as local time, or
NULL if don't want to
know */
@ -812,14 +810,14 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
{
NTP_Packet message;
int auth_len, length, ret, precision;
struct timeval local_receive, local_transmit;
struct timespec local_receive, local_transmit;
NTP_int64 ts_fuzz;
/* Parameters read from reference module */
int are_we_synchronised, our_stratum, smooth_time;
NTP_Leap leap_status;
uint32_t our_ref_id;
struct timeval our_ref_time;
struct timespec our_ref_time;
double our_root_delay, our_root_dispersion, smooth_offset;
/* Don't reply with version higher than ours */
@ -834,8 +832,8 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
/* Don't reveal local time or state of the clock in client packets */
precision = 32;
leap_status = our_stratum = our_ref_id = 0;
our_ref_time.tv_sec = our_ref_time.tv_usec = 0;
our_root_delay = our_root_dispersion = 0.0;
UTI_ZeroTimespec(&our_ref_time);
} else {
/* This is accurate enough and cheaper than calling LCL_ReadCookedTime.
A more accurate timestamp will be taken later in this function. */
@ -863,8 +861,8 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
if (smooth_time) {
our_ref_id = NTP_REFID_SMOOTH;
UTI_AddDoubleToTimeval(&our_ref_time, smooth_offset, &our_ref_time);
UTI_AddDoubleToTimeval(local_rx, smooth_offset, &local_receive);
UTI_AddDoubleToTimespec(&our_ref_time, smooth_offset, &our_ref_time);
UTI_AddDoubleToTimespec(local_rx, smooth_offset, &local_receive);
} else {
local_receive = *local_rx;
}
@ -890,7 +888,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
/* Now fill in timestamps */
UTI_TimevalToInt64(&our_ref_time, &message.reference_ts, NULL);
UTI_TimespecToInt64(&our_ref_time, &message.reference_ts, NULL);
/* Originate - this comes from the last packet the source sent us */
message.originate_ts = *orig_ts;
@ -902,7 +900,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
This timestamp will have been adjusted so that it will now look to
the source like we have been running on our latest estimate of
frequency all along */
UTI_TimevalToInt64(&local_receive, &message.receive_ts, &ts_fuzz);
UTI_TimespecToInt64(&local_receive, &message.receive_ts, &ts_fuzz);
/* Prepare random bits which will be added to the transmit timestamp. */
UTI_GetInt64Fuzz(&ts_fuzz, precision);
@ -913,7 +911,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
LCL_ReadCookedTime(&local_transmit, NULL);
if (smooth_time)
UTI_AddDoubleToTimeval(&local_transmit, smooth_offset, &local_transmit);
UTI_AddDoubleToTimespec(&local_transmit, smooth_offset, &local_transmit);
length = NTP_NORMAL_PACKET_LENGTH;
@ -922,10 +920,10 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
if (auth_mode == AUTH_SYMMETRIC || auth_mode == AUTH_MSSNTP) {
/* Pre-compensate the transmit time by approx. how long it will
take to generate the authentication data. */
local_transmit.tv_usec += auth_mode == AUTH_SYMMETRIC ?
local_transmit.tv_nsec += auth_mode == AUTH_SYMMETRIC ?
KEY_GetAuthDelay(key_id) : NSD_GetAuthDelay(key_id);
UTI_NormaliseTimeval(&local_transmit);
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, &ts_fuzz);
UTI_NormaliseTimespec(&local_transmit);
UTI_TimespecToInt64(&local_transmit, &message.transmit_ts, &ts_fuzz);
if (auth_mode == AUTH_SYMMETRIC) {
auth_len = KEY_GenerateAuth(key_id, (unsigned char *) &message,
@ -943,7 +941,7 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
return NSD_SignAndSendPacket(key_id, &message, where_to, from, length);
}
} else {
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, &ts_fuzz);
UTI_TimespecToInt64(&local_transmit, &message.transmit_ts, &ts_fuzz);
}
ret = NIO_SendPacket(&message, where_to, from, length);
@ -1191,7 +1189,7 @@ check_packet_auth(NTP_Packet *pkt, int length,
/* ================================================== */
static int
receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Instance inst, NTP_Local_Address *local_addr, int length)
receive_packet(NTP_Packet *message, struct timespec *now, double now_err, NCR_Instance inst, NTP_Local_Address *local_addr, int length)
{
int pkt_leap;
uint32_t pkt_refid, pkt_key_id;
@ -1204,7 +1202,7 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
the same as either the transmit or receive time. The difference comes
in symmetric active mode, when the receive may come minutes after the
transmit, and this time will be midway between the two */
struct timeval sample_time;
struct timespec sample_time;
/* The estimated offset in seconds, a positive value indicates that the local
clock is SLOW of the remote source and a negative value indicates that the
@ -1220,9 +1218,9 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
/* The skew and estimated frequency offset relative to the remote source */
double skew, source_freq_lo, source_freq_hi;
/* These are the timeval equivalents of the remote epochs */
struct timeval remote_receive_tv, remote_transmit_tv;
struct timeval local_average, remote_average;
/* These are the timespec equivalents of the remote epochs */
struct timespec remote_receive, remote_transmit;
struct timespec local_average, remote_average;
double local_interval, remote_interval;
/* RFC 5905 packet tests */
@ -1257,8 +1255,8 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
pkt_root_delay = UTI_Int32ToDouble(message->root_delay);
pkt_root_dispersion = UTI_Int32ToDouble(message->root_dispersion);
UTI_Int64ToTimeval(&message->receive_ts, &remote_receive_tv);
UTI_Int64ToTimeval(&message->transmit_ts, &remote_transmit_tv);
UTI_Int64ToTimespec(&message->receive_ts, &remote_receive);
UTI_Int64ToTimespec(&message->transmit_ts, &remote_transmit);
/* Check if the packet is valid per RFC 5905, section 8.
The test values are 1 when passed and 0 when failed. */
@ -1330,11 +1328,11 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
SRC_GetFrequencyRange(inst->source, &source_freq_lo, &source_freq_hi);
UTI_AverageDiffTimevals(&remote_receive_tv, &remote_transmit_tv,
&remote_average, &remote_interval);
UTI_AverageDiffTimespecs(&remote_receive, &remote_transmit,
&remote_average, &remote_interval);
UTI_AverageDiffTimevals(&inst->local_tx, now,
&local_average, &local_interval);
UTI_AverageDiffTimespecs(&inst->local_tx, now,
&local_average, &local_interval);
/* In our case, we work out 'delay' as the worst case delay,
assuming worst case frequency error between us and the other
@ -1348,7 +1346,7 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
/* Calculate offset. Following the NTP definition, this is negative
if we are fast of the remote source. */
UTI_DiffTimevalsToDouble(&offset, &remote_average, &local_average);
UTI_DiffTimespecsToDouble(&offset, &remote_average, &local_average);
/* Apply configured correction */
offset += inst->offset_correction;
@ -1549,7 +1547,7 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
int
NCR_ProcessKnown
(NTP_Packet *message, /* the received message */
struct timeval *now, /* timestamp at time of receipt */
struct timespec *now, /* timestamp at time of receipt */
double now_err,
NCR_Instance inst, /* the instance record for this peer/server */
NTP_Local_Address *local_addr, /* the receiving address */
@ -1681,7 +1679,7 @@ NCR_ProcessKnown
void
NCR_ProcessUnknown
(NTP_Packet *message, /* the received message */
struct timeval *now, /* timestamp at time of receipt */
struct timespec *now, /* timestamp at time of receipt */
double now_err, /* assumed error in the timestamp */
NTP_Remote_Address *remote_addr,
NTP_Local_Address *local_addr,
@ -1768,14 +1766,14 @@ NCR_ProcessUnknown
/* ================================================== */
void
NCR_SlewTimes(NCR_Instance inst, struct timeval *when, double dfreq, double doffset)
NCR_SlewTimes(NCR_Instance inst, struct timespec *when, double dfreq, double doffset)
{
double delta;
if (inst->local_rx.tv_sec || inst->local_rx.tv_usec)
UTI_AdjustTimeval(&inst->local_rx, when, &inst->local_rx, &delta, dfreq, doffset);
if (inst->local_tx.tv_sec || inst->local_tx.tv_usec)
UTI_AdjustTimeval(&inst->local_tx, when, &inst->local_tx, &delta, dfreq, doffset);
if (inst->local_rx.tv_sec || inst->local_rx.tv_nsec)
UTI_AdjustTimespec(&inst->local_rx, when, &inst->local_rx, &delta, dfreq, doffset);
if (inst->local_tx.tv_sec || inst->local_tx.tv_nsec)
UTI_AdjustTimespec(&inst->local_tx, when, &inst->local_tx, &delta, dfreq, doffset);
}
/* ================================================== */
@ -1940,7 +1938,7 @@ NCR_InitiateSampleBurst(NCR_Instance inst, int n_good_samples, int n_total_sampl
/* ================================================== */
void
NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timeval *now)
NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timespec *now)
{
report->poll = inst->local_poll;
@ -2073,14 +2071,13 @@ broadcast_timeout(void *arg)
{
BroadcastDestination *destination;
NTP_int64 orig_ts;
struct timeval recv_ts;
struct timespec recv_ts;
destination = ARR_GetElement(broadcasts, (long)arg);
orig_ts.hi = 0;
orig_ts.lo = 0;
recv_ts.tv_sec = 0;
recv_ts.tv_usec = 0;
UTI_ZeroTimespec(&recv_ts);
transmit_packet(MODE_BROADCAST, 6 /* FIXME: should this be log2(interval)? */,
NTP_VERSION, 0, 0, &orig_ts, &recv_ts, NULL, NULL,

View file

@ -63,14 +63,14 @@ extern void NCR_ChangeRemoteAddress(NCR_Instance inst, NTP_Remote_Address *remot
/* This routine is called when a new packet arrives off the network,
and it relates to a source we have an ongoing protocol exchange with */
extern int NCR_ProcessKnown(NTP_Packet *message, struct timeval *now, double now_err, NCR_Instance data, NTP_Local_Address *local_addr, int length);
extern int NCR_ProcessKnown(NTP_Packet *message, struct timespec *now, double now_err, NCR_Instance data, NTP_Local_Address *local_addr, int length);
/* This routine is called when a new packet arrives off the network,
and we do not recognize its source */
extern void NCR_ProcessUnknown(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length);
extern void NCR_ProcessUnknown(NTP_Packet *message, struct timespec *now, double now_err, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length);
/* Slew receive and transmit times in instance records */
extern void NCR_SlewTimes(NCR_Instance inst, struct timeval *when, double dfreq, double doffset);
extern void NCR_SlewTimes(NCR_Instance inst, struct timespec *when, double dfreq, double doffset);
/* Take a particular source online (i.e. start sampling it) */
extern void NCR_TakeSourceOnline(NCR_Instance inst);
@ -95,7 +95,7 @@ extern void NCR_ModifyPolltarget(NCR_Instance inst, int new_poll_target);
extern void NCR_InitiateSampleBurst(NCR_Instance inst, int n_good_samples, int n_total_samples);
extern void NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timeval *now);
extern void NCR_ReportSource(NCR_Instance inst, RPT_SourceReport *report, struct timespec *now);
extern int NCR_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all);
extern int NCR_CheckAccessRestriction(IPAddr *ip_addr);

View file

@ -549,7 +549,7 @@ process_receive(struct msghdr *hdr, int length, int sock_fd)
NTP_Remote_Address remote_addr;
NTP_Local_Address local_addr;
struct cmsghdr *cmsg;
struct timeval now;
struct timespec now;
double now_err;
SCH_GetLastEventTime(&now, &now_err, NULL);
@ -590,9 +590,11 @@ process_receive(struct msghdr *hdr, int length, int sock_fd)
#ifdef SO_TIMESTAMP
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
struct timeval tv;
struct timespec ts;
memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));
LCL_CookTime(&tv, &now, &now_err);
UTI_TimevalToTimespec(&tv, &ts);
LCL_CookTime(&ts, &now, &now_err);
}
#endif
}

View file

@ -73,7 +73,7 @@ typedef struct {
int sent;
int received;
int request_length;
struct timeval request_tv;
struct timespec request_ts;
SigndRequest request;
SigndResponse response;
} SignInstance;
@ -166,7 +166,7 @@ open_socket(void)
static void
process_response(SignInstance *inst)
{
struct timeval tv;
struct timespec ts;
double delay;
if (ntohs(inst->request.packet_id) != ntohl(inst->response.packet_id)) {
@ -185,8 +185,8 @@ process_response(SignInstance *inst)
return;
}
SCH_GetLastEventTime(NULL, NULL, &tv);
UTI_DiffTimevalsToDouble(&delay, &tv, &inst->request_tv);
SCH_GetLastEventTime(NULL, NULL, &ts);
UTI_DiffTimespecsToDouble(&delay, &ts, &inst->request_ts);
DEBUG_LOG(LOGF_NtpSignd, "Signing succeeded (delay %f)", delay);
@ -216,7 +216,7 @@ read_write_socket(int sock_fd, int event, void *anything)
assert(inst->sent < inst->request_length);
if (!inst->sent)
SCH_GetLastEventTime(NULL, NULL, &inst->request_tv);
SCH_GetLastEventTime(NULL, NULL, &inst->request_ts);
s = send(sock_fd, (char *)&inst->request + inst->sent,
inst->request_length - inst->sent, 0);
@ -322,7 +322,7 @@ NSD_Finalise()
extern int NSD_GetAuthDelay(uint32_t key_id)
{
return auth_delay * 1.0e6;
return 1.0e9 * auth_delay;
}
/* ================================================== */

View file

@ -117,8 +117,8 @@ static void rehash_records(void);
static void clean_source_record(SourceRecord *record);
static void
slew_sources(struct timeval *raw,
struct timeval *cooked,
slew_sources(struct timespec *raw,
struct timespec *cooked,
double dfreq,
double doffset,
LCL_ChangeType change_type,
@ -680,8 +680,8 @@ resolve_source_replacement(SourceRecord *record)
void
NSR_HandleBadSource(IPAddr *address)
{
static struct timeval last_replacement;
struct timeval now;
static struct timespec last_replacement;
struct timespec now;
NTP_Remote_Address remote_addr;
SourceRecord *record;
int slot, found;
@ -702,7 +702,7 @@ NSR_HandleBadSource(IPAddr *address)
/* Don't resolve names too frequently */
SCH_GetLastEventTime(NULL, NULL, &now);
UTI_DiffTimevalsToDouble(&diff, &now, &last_replacement);
UTI_DiffTimespecsToDouble(&diff, &now, &last_replacement);
if (fabs(diff) < RESOLVE_INTERVAL_UNIT * (1 << MIN_REPLACEMENT_INTERVAL)) {
DEBUG_LOG(LOGF_NtpSources, "replacement postponed");
return;
@ -776,7 +776,7 @@ NSR_GetLocalRefid(IPAddr *address)
/* This routine is called by ntp_io when a new packet arrives off the network,
possibly with an authentication tail */
void
NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length)
NSR_ProcessReceive(NTP_Packet *message, struct timespec *now, double now_err, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length)
{
SourceRecord *record;
struct SourcePool *pool;
@ -816,8 +816,8 @@ NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP
/* ================================================== */
static void
slew_sources(struct timeval *raw,
struct timeval *cooked,
slew_sources(struct timespec *raw,
struct timespec *cooked,
double dfreq,
double doffset,
LCL_ChangeType change_type,
@ -1083,7 +1083,7 @@ NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples,
identify the source record. */
void
NSR_ReportSource(RPT_SourceReport *report, struct timeval *now)
NSR_ReportSource(RPT_SourceReport *report, struct timespec *now)
{
NTP_Remote_Address rem_addr;
int slot, found;

View file

@ -87,7 +87,7 @@ extern void NSR_RefreshAddresses(void);
extern uint32_t NSR_GetLocalRefid(IPAddr *address);
/* This routine is called by ntp_io when a new packet arrives off the network */
extern void NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length);
extern void NSR_ProcessReceive(NTP_Packet *message, struct timespec *now, double now_err, NTP_Remote_Address *remote_addr, NTP_Local_Address *local_addr, int length);
/* Initialisation function */
extern void NSR_Initialise(void);
@ -121,7 +121,7 @@ extern int NSR_ModifyPolltarget(IPAddr *address, int new_poll_target);
extern int NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples, IPAddr *mask, IPAddr *address);
extern void NSR_ReportSource(RPT_SourceReport *report, struct timeval *now);
extern void NSR_ReportSource(RPT_SourceReport *report, struct timespec *now);
extern void NSR_GetActivityReport(RPT_ActivityReport *report);

View file

@ -48,7 +48,7 @@ extern RefclockDriver RCL_PHC_driver;
struct FilterSample {
double offset;
double dispersion;
struct timeval sample_time;
struct timespec sample_time;
};
struct MedianFilter {
@ -92,23 +92,23 @@ static ARR_Instance refclocks;
static LOG_FileID logfileid;
static int valid_sample_time(RCL_Instance instance, struct timeval *tv);
static int pps_stratum(RCL_Instance instance, struct timeval *tv);
static int valid_sample_time(RCL_Instance instance, struct timespec *ts);
static int pps_stratum(RCL_Instance instance, struct timespec *ts);
static void poll_timeout(void *arg);
static void slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq,
static void slew_samples(struct timespec *raw, struct timespec *cooked, double dfreq,
double doffset, LCL_ChangeType change_type, void *anything);
static void add_dispersion(double dispersion, void *anything);
static void log_sample(RCL_Instance instance, struct timeval *sample_time, int filtered, int pulse, double raw_offset, double cooked_offset, double dispersion);
static void log_sample(RCL_Instance instance, struct timespec *sample_time, int filtered, int pulse, double raw_offset, double cooked_offset, double dispersion);
static void filter_init(struct MedianFilter *filter, int length, double max_dispersion);
static void filter_fini(struct MedianFilter *filter);
static void filter_reset(struct MedianFilter *filter);
static double filter_get_avg_sample_dispersion(struct MedianFilter *filter);
static void filter_add_sample(struct MedianFilter *filter, struct timeval *sample_time, double offset, double dispersion);
static int filter_get_last_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion);
static void filter_add_sample(struct MedianFilter *filter, struct timespec *sample_time, double offset, double dispersion);
static int filter_get_last_sample(struct MedianFilter *filter, struct timespec *sample_time, double *offset, double *dispersion);
static int filter_select_samples(struct MedianFilter *filter);
static int filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion);
static void filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset);
static int filter_get_sample(struct MedianFilter *filter, struct timespec *sample_time, double *offset, double *dispersion);
static void filter_slew_samples(struct MedianFilter *filter, struct timespec *when, double dfreq, double doffset);
static void filter_add_dispersion(struct MedianFilter *filter, double dispersion);
static RCL_Instance
@ -299,7 +299,7 @@ RCL_StartRefclocks(void)
}
void
RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
RCL_ReportSource(RPT_SourceReport *report, struct timespec *now)
{
unsigned int i;
uint32_t ref_id;
@ -361,13 +361,13 @@ RCL_GetDriverOption(RCL_Instance instance, char *name)
}
int
RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, int leap)
RCL_AddSample(RCL_Instance instance, struct timespec *sample_time, double offset, int leap)
{
double correction, dispersion;
struct timeval cooked_time;
struct timespec cooked_time;
LCL_GetOffsetCorrection(sample_time, &correction, &dispersion);
UTI_AddDoubleToTimeval(sample_time, correction, &cooked_time);
UTI_AddDoubleToTimespec(sample_time, correction, &cooked_time);
dispersion += instance->precision;
/* Make sure the timestamp and offset provided by the driver are sane */
@ -399,16 +399,16 @@ RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset,
}
int
RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
RCL_AddPulse(RCL_Instance instance, struct timespec *pulse_time, double second)
{
double correction, dispersion, offset;
struct timeval cooked_time;
struct timespec cooked_time;
int rate;
NTP_Leap leap;
leap = LEAP_Normal;
LCL_GetOffsetCorrection(pulse_time, &correction, &dispersion);
UTI_AddDoubleToTimeval(pulse_time, correction, &cooked_time);
UTI_AddDoubleToTimespec(pulse_time, correction, &cooked_time);
dispersion += instance->precision;
if (!UTI_IsTimeOffsetSane(pulse_time, 0.0) ||
@ -429,7 +429,7 @@ RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
if (instance->lock_ref != -1) {
RCL_Instance lock_refclock;
struct timeval ref_sample_time;
struct timespec ref_sample_time;
double sample_diff, ref_offset, ref_dispersion, shift;
lock_refclock = get_refclock(instance->lock_ref);
@ -442,7 +442,7 @@ RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
ref_dispersion += filter_get_avg_sample_dispersion(&lock_refclock->filter);
UTI_DiffTimevalsToDouble(&sample_diff, &cooked_time, &ref_sample_time);
UTI_DiffTimespecsToDouble(&sample_diff, &cooked_time, &ref_sample_time);
if (fabs(sample_diff) >= 2.0 / rate) {
DEBUG_LOG(LOGF_Refclock, "refclock pulse ignored samplediff=%.9f",
sample_diff);
@ -468,7 +468,7 @@ RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
DEBUG_LOG(LOGF_Refclock, "refclock pulse second=%.9f offset=%.9f offdiff=%.9f samplediff=%.9f",
second, offset, ref_offset - offset, sample_diff);
} else {
struct timeval ref_time;
struct timespec ref_time;
int is_synchronised, stratum;
double root_delay, root_dispersion, distance;
uint32_t ref_id;
@ -503,25 +503,25 @@ RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
}
static int
valid_sample_time(RCL_Instance instance, struct timeval *tv)
valid_sample_time(RCL_Instance instance, struct timespec *ts)
{
struct timeval raw_time;
struct timespec raw_time;
double diff;
LCL_ReadRawTime(&raw_time);
UTI_DiffTimevalsToDouble(&diff, &raw_time, tv);
UTI_DiffTimespecsToDouble(&diff, &raw_time, ts);
if (diff < 0.0 || diff > UTI_Log2ToDouble(instance->poll + 1)) {
DEBUG_LOG(LOGF_Refclock, "%s refclock sample not valid age=%.6f tv=%s",
UTI_RefidToString(instance->ref_id), diff, UTI_TimevalToString(tv));
DEBUG_LOG(LOGF_Refclock, "%s refclock sample not valid age=%.6f ts=%s",
UTI_RefidToString(instance->ref_id), diff, UTI_TimespecToString(ts));
return 0;
}
return 1;
}
static int
pps_stratum(RCL_Instance instance, struct timeval *tv)
pps_stratum(RCL_Instance instance, struct timespec *ts)
{
struct timeval ref_time;
struct timespec ref_time;
int is_synchronised, stratum;
unsigned int i;
double root_delay, root_dispersion;
@ -529,7 +529,7 @@ pps_stratum(RCL_Instance instance, struct timeval *tv)
uint32_t ref_id;
RCL_Instance refclock;
REF_GetReferenceParams(tv, &is_synchronised, &leap, &stratum,
REF_GetReferenceParams(ts, &is_synchronised, &leap, &stratum,
&ref_id, &ref_time, &root_delay, &root_dispersion);
/* Don't change our stratum if the local reference is active
@ -566,7 +566,7 @@ poll_timeout(void *arg)
if (!(inst->driver->poll && inst->driver_polled < (1 << (inst->poll - inst->driver_poll)))) {
double offset, dispersion;
struct timeval sample_time;
struct timespec sample_time;
int sample_ok, stratum;
sample_ok = filter_get_sample(&inst->filter, &sample_time, &offset, &dispersion);
@ -594,7 +594,7 @@ poll_timeout(void *arg)
}
static void
slew_samples(struct timeval *raw, struct timeval *cooked, double dfreq,
slew_samples(struct timespec *raw, struct timespec *cooked, double dfreq,
double doffset, LCL_ChangeType change_type, void *anything)
{
unsigned int i;
@ -617,7 +617,7 @@ add_dispersion(double dispersion, void *anything)
}
static void
log_sample(RCL_Instance instance, struct timeval *sample_time, int filtered, int pulse, double raw_offset, double cooked_offset, double dispersion)
log_sample(RCL_Instance instance, struct timespec *sample_time, int filtered, int pulse, double raw_offset, double cooked_offset, double dispersion)
{
char sync_stats[4] = {'N', '+', '-', '?'};
@ -627,7 +627,7 @@ log_sample(RCL_Instance instance, struct timeval *sample_time, int filtered, int
if (!filtered) {
LOG_FileWrite(logfileid, "%s.%06d %-5s %3d %1c %1d %13.6e %13.6e %10.3e",
UTI_TimeToLogForm(sample_time->tv_sec),
(int)sample_time->tv_usec,
(int)sample_time->tv_nsec / 1000,
UTI_RefidToString(instance->ref_id),
instance->driver_polled,
sync_stats[instance->leap_status],
@ -638,7 +638,7 @@ log_sample(RCL_Instance instance, struct timeval *sample_time, int filtered, int
} else {
LOG_FileWrite(logfileid, "%s.%06d %-5s - %1c - - %13.6e %10.3e",
UTI_TimeToLogForm(sample_time->tv_sec),
(int)sample_time->tv_usec,
(int)sample_time->tv_nsec / 1000,
UTI_RefidToString(instance->ref_id),
sync_stats[instance->leap_status],
cooked_offset,
@ -691,7 +691,7 @@ filter_get_avg_sample_dispersion(struct MedianFilter *filter)
}
static void
filter_add_sample(struct MedianFilter *filter, struct timeval *sample_time, double offset, double dispersion)
filter_add_sample(struct MedianFilter *filter, struct timespec *sample_time, double offset, double dispersion)
{
filter->index++;
filter->index %= filter->length;
@ -704,11 +704,11 @@ filter_add_sample(struct MedianFilter *filter, struct timeval *sample_time, doub
filter->samples[filter->index].dispersion = dispersion;
DEBUG_LOG(LOGF_Refclock, "filter sample %d t=%s offset=%.9f dispersion=%.9f",
filter->index, UTI_TimevalToString(sample_time), offset, dispersion);
filter->index, UTI_TimespecToString(sample_time), offset, dispersion);
}
static int
filter_get_last_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion)
filter_get_last_sample(struct MedianFilter *filter, struct timespec *sample_time, double *offset, double *dispersion)
{
if (filter->last < 0)
return 0;
@ -821,7 +821,7 @@ filter_select_samples(struct MedianFilter *filter)
}
static int
filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion)
filter_get_sample(struct MedianFilter *filter, struct timespec *sample_time, double *offset, double *dispersion)
{
struct FilterSample *s, *ls;
int i, n, dof;
@ -838,7 +838,7 @@ filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, doub
for (i = 0; i < n; i++) {
s = &filter->samples[filter->selected[i]];
UTI_DiffTimevalsToDouble(&filter->x_data[i], &s->sample_time, &ls->sample_time);
UTI_DiffTimespecsToDouble(&filter->x_data[i], &s->sample_time, &ls->sample_time);
filter->y_data[i] = s->offset;
filter->w_data[i] = s->dispersion;
}
@ -913,7 +913,7 @@ filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, doub
if (d < e)
d = e;
UTI_AddDoubleToTimeval(&ls->sample_time, x, sample_time);
UTI_AddDoubleToTimespec(&ls->sample_time, x, sample_time);
*offset = y;
*dispersion = d;
@ -923,15 +923,15 @@ filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, doub
}
static void
filter_slew_samples(struct MedianFilter *filter, struct timeval *when, double dfreq, double doffset)
filter_slew_samples(struct MedianFilter *filter, struct timespec *when, double dfreq, double doffset)
{
int i;
double delta_time;
struct timeval *sample;
struct timespec *sample;
for (i = 0; i < filter->used; i++) {
sample = &filter->samples[i].sample_time;
UTI_AdjustTimeval(sample, when, sample, &delta_time, dfreq, doffset);
UTI_AdjustTimespec(sample, when, sample, &delta_time, dfreq, doffset);
filter->samples[i].offset -= delta_time;
}
}

View file

@ -61,14 +61,14 @@ extern void RCL_Initialise(void);
extern void RCL_Finalise(void);
extern int RCL_AddRefclock(RefclockParameters *params);
extern void RCL_StartRefclocks(void);
extern void RCL_ReportSource(RPT_SourceReport *report, struct timeval *now);
extern void RCL_ReportSource(RPT_SourceReport *report, struct timespec *now);
/* functions used by drivers */
extern void RCL_SetDriverData(RCL_Instance instance, void *data);
extern void *RCL_GetDriverData(RCL_Instance instance);
extern char *RCL_GetDriverParameter(RCL_Instance instance);
extern char *RCL_GetDriverOption(RCL_Instance instance, char *name);
extern int RCL_AddSample(RCL_Instance instance, struct timeval *sample_time, double offset, int leap);
extern int RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second);
extern int RCL_AddSample(RCL_Instance instance, struct timespec *sample_time, double offset, int leap);
extern int RCL_AddPulse(RCL_Instance instance, struct timespec *pulse_time, double second);
#endif

View file

@ -56,11 +56,6 @@ struct phc_reading {
struct timespec sys_ts2;
};
static double diff_ts(struct timespec *ts1, struct timespec *ts2)
{
return (ts1->tv_sec - ts2->tv_sec) + (ts1->tv_nsec - ts2->tv_nsec) / 1e9;
}
static int read_phc_ioctl(struct phc_reading *readings, int phc_fd, int n)
{
#if defined(PTP_SYS_OFFSET) && NUM_READINGS <= PTP_MAX_SAMPLES
@ -145,7 +140,6 @@ static void phc_finalise(RCL_Instance instance)
static int phc_poll(RCL_Instance instance)
{
struct phc_reading readings[NUM_READINGS];
struct timeval tv;
double offset = 0.0, delay, best_delay = 0.0;
int i, phc_fd, best;
@ -163,7 +157,7 @@ static int phc_poll(RCL_Instance instance)
/* Find the fastest reading */
for (i = 0; i < NUM_READINGS; i++) {
delay = diff_ts(&readings[i].sys_ts2, &readings[i].sys_ts1);
UTI_DiffTimespecsToDouble(&delay, &readings[i].sys_ts2, &readings[i].sys_ts1);
if (!i || best_delay > delay) {
best = i;
@ -171,13 +165,12 @@ static int phc_poll(RCL_Instance instance)
}
}
offset = diff_ts(&readings[best].phc_ts, &readings[best].sys_ts2) + best_delay / 2.0;
tv.tv_sec = readings[best].sys_ts2.tv_sec;
tv.tv_usec = readings[best].sys_ts2.tv_nsec / 1000;
UTI_DiffTimespecsToDouble(&offset, &readings[best].phc_ts, &readings[best].sys_ts2);
offset += best_delay / 2.0;
DEBUG_LOG(LOGF_Refclock, "PHC offset: %+.9f delay: %.9f", offset, best_delay);
return RCL_AddSample(instance, &tv, offset, LEAP_Normal);
return RCL_AddSample(instance, &readings[best].sys_ts2, offset, LEAP_Normal);
}
RefclockDriver RCL_PHC_driver = {

View file

@ -124,7 +124,6 @@ static int pps_poll(RCL_Instance instance)
{
struct pps_instance *pps;
struct timespec ts;
struct timeval tv;
pps_info_t pps_info;
pps_seq_t seq;
@ -153,10 +152,8 @@ static int pps_poll(RCL_Instance instance)
}
pps->last_seq = seq;
tv.tv_sec = ts.tv_sec;
tv.tv_usec = ts.tv_nsec / 1000;
return RCL_AddPulse(instance, &tv, ts.tv_nsec / 1e9);
return RCL_AddPulse(instance, &ts, 1.0e-9 * ts.tv_nsec);
}
RefclockDriver RCL_PPS_driver = {

View file

@ -90,7 +90,7 @@ static void shm_finalise(RCL_Instance instance)
static int shm_poll(RCL_Instance instance)
{
struct timeval tv;
struct timespec receive_ts, clock_ts;
struct shmTime t, *shm;
double offset;
@ -107,17 +107,23 @@ static int shm_poll(RCL_Instance instance)
shm->valid = 0;
tv.tv_sec = t.receiveTimeStampSec;
tv.tv_usec = t.receiveTimeStampUSec;
receive_ts.tv_sec = t.receiveTimeStampSec;
clock_ts.tv_sec = t.clockTimeStampSec;
offset = t.clockTimeStampSec - t.receiveTimeStampSec;
if (t.clockTimeStampNSec / 1000 == t.clockTimeStampUSec &&
t.receiveTimeStampNSec / 1000 == t.receiveTimeStampUSec)
offset += (t.clockTimeStampNSec - t.receiveTimeStampNSec) * 1e-9;
else
offset += (t.clockTimeStampUSec - t.receiveTimeStampUSec) * 1e-6;
t.receiveTimeStampNSec / 1000 == t.receiveTimeStampUSec) {
receive_ts.tv_nsec = t.receiveTimeStampNSec;
clock_ts.tv_nsec = t.clockTimeStampNSec;
} else {
receive_ts.tv_nsec = 1000 * t.receiveTimeStampUSec;
clock_ts.tv_nsec = 1000 * t.clockTimeStampUSec;
}
return RCL_AddSample(instance, &tv, offset, t.leap);
UTI_NormaliseTimespec(&clock_ts);
UTI_NormaliseTimespec(&receive_ts);
UTI_DiffTimespecsToDouble(&offset, &clock_ts, &receive_ts);
return RCL_AddSample(instance, &receive_ts, offset, t.leap);
}
RefclockDriver RCL_SHM_driver = {

View file

@ -60,6 +60,7 @@ struct sock_sample {
static void read_sample(int sockfd, int event, void *anything)
{
struct sock_sample sample;
struct timespec ts;
RCL_Instance instance;
int s;
@ -85,10 +86,13 @@ static void read_sample(int sockfd, int event, void *anything)
return;
}
UTI_TimevalToTimespec(&sample.tv, &ts);
UTI_NormaliseTimespec(&ts);
if (sample.pulse) {
RCL_AddPulse(instance, &sample.tv, sample.offset);
RCL_AddPulse(instance, &ts, sample.offset);
} else {
RCL_AddSample(instance, &sample.tv, sample.offset, sample.leap);
RCL_AddSample(instance, &ts, sample.offset, sample.leap);
}
}

View file

@ -52,7 +52,7 @@ static int our_leap_sec;
static int our_stratum;
static uint32_t our_ref_id;
static IPAddr our_ref_ip;
struct timeval our_ref_time;
struct timespec our_ref_time;
static double our_skew;
static double our_residual_freq;
static double our_root_delay;
@ -136,7 +136,7 @@ static int next_fb_drift;
static SCH_TimeoutID fb_drift_timeout_id;
/* Timestamp of last reference update */
static struct timeval last_ref_update;
static struct timespec last_ref_update;
static double last_ref_update_interval;
/* ================================================== */
@ -147,23 +147,22 @@ static void update_leap_status(NTP_Leap leap, time_t now, int reset);
/* ================================================== */
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,
void *anything)
{
double delta;
struct timeval now;
struct timespec now;
UTI_AdjustTimeval(&our_ref_time, cooked, &our_ref_time, &delta, dfreq, doffset);
UTI_AdjustTimespec(&our_ref_time, cooked, &our_ref_time, &delta, dfreq, doffset);
if (change_type == LCL_ChangeUnknownStep) {
last_ref_update.tv_sec = 0;
last_ref_update.tv_usec = 0;
UTI_ZeroTimespec(&last_ref_update);
} else if (last_ref_update.tv_sec) {
UTI_AdjustTimeval(&last_ref_update, cooked, &last_ref_update, &delta, dfreq, doffset);
UTI_AdjustTimespec(&last_ref_update, cooked, &last_ref_update, &delta, dfreq, doffset);
}
/* When the clock was stepped, check if that doesn't change our leap status
@ -267,8 +266,7 @@ REF_Initialise(void)
fb_drift_timeout_id = 0;
}
last_ref_update.tv_sec = 0;
last_ref_update.tv_usec = 0;
UTI_ZeroTimespec(&last_ref_update);
last_ref_update_interval = 0.0;
LCL_AddParameterChangeHandler(handle_slew, NULL);
@ -468,16 +466,16 @@ fb_drift_timeout(void *arg)
/* ================================================== */
static void
schedule_fb_drift(struct timeval *now)
schedule_fb_drift(struct timespec *now)
{
int i, c, secs;
double unsynchronised;
struct timeval when;
struct timespec when;
if (fb_drift_timeout_id)
return; /* already scheduled */
UTI_DiffTimevalsToDouble(&unsynchronised, now, &last_ref_update);
UTI_DiffTimespecsToDouble(&unsynchronised, now, &last_ref_update);
for (c = secs = 0, i = fb_drift_min; i <= fb_drift_max; i++) {
secs = 1 << i;
@ -499,7 +497,7 @@ schedule_fb_drift(struct timeval *now)
if (i <= fb_drift_max) {
next_fb_drift = i;
UTI_AddDoubleToTimeval(now, secs - unsynchronised, &when);
UTI_AddDoubleToTimespec(now, secs - unsynchronised, &when);
fb_drift_timeout_id = SCH_AddTimeout(&when, fb_drift_timeout, NULL);
DEBUG_LOG(LOGF_Reference, "Fallback drift %d scheduled", i);
}
@ -727,7 +725,7 @@ leap_start_timeout(void *arg)
static void
set_leap_timeout(time_t now)
{
struct timeval when;
struct timespec when;
/* Stop old timer if there is one */
SCH_RemoveTimeout(leap_timeout_id);
@ -741,12 +739,12 @@ set_leap_timeout(time_t now)
will be corrected by the system, timeout slightly sooner to be sure it
will happen before the system correction. */
when.tv_sec = (now / (24 * 3600) + 1) * (24 * 3600);
when.tv_usec = 0;
when.tv_nsec = 0;
if (our_leap_sec < 0)
when.tv_sec--;
if (leap_mode == REF_LeapModeSystem) {
when.tv_sec--;
when.tv_usec = 500000;
when.tv_nsec = 500000000;
}
leap_timeout_id = SCH_AddTimeout(&when, leap_start_timeout, NULL);
@ -804,7 +802,7 @@ update_leap_status(NTP_Leap leap, time_t now, int reset)
/* ================================================== */
static void
write_log(struct timeval *ref_time, char *ref, int stratum, NTP_Leap leap,
write_log(struct timespec *ref_time, char *ref, int stratum, NTP_Leap leap,
double freq, double skew, double offset, int combined_sources,
double offset_sd, double uncorrected_offset)
{
@ -881,7 +879,7 @@ REF_SetReference(int stratum,
int combined_sources,
uint32_t ref_id,
IPAddr *ref_ip,
struct timeval *ref_time,
struct timespec *ref_time,
double offset,
double offset_sd,
double frequency,
@ -902,7 +900,7 @@ REF_SetReference(int stratum,
double elapsed;
double correction_rate;
double uncorrected_offset, accumulate_offset, step_offset;
struct timeval now, raw_now;
struct timespec now, raw_now;
assert(initialised);
@ -936,9 +934,9 @@ REF_SetReference(int stratum,
LCL_ReadRawTime(&raw_now);
LCL_GetOffsetCorrection(&raw_now, &uncorrected_offset, NULL);
UTI_AddDoubleToTimeval(&raw_now, uncorrected_offset, &now);
UTI_AddDoubleToTimespec(&raw_now, uncorrected_offset, &now);
UTI_DiffTimevalsToDouble(&elapsed, &now, ref_time);
UTI_DiffTimespecsToDouble(&elapsed, &now, ref_time);
our_offset = offset + elapsed * frequency;
if (!is_offset_ok(our_offset))
@ -956,7 +954,7 @@ REF_SetReference(int stratum,
our_root_dispersion = root_dispersion;
if (last_ref_update.tv_sec) {
UTI_DiffTimevalsToDouble(&update_interval, &now, &last_ref_update);
UTI_DiffTimespecsToDouble(&update_interval, &now, &last_ref_update);
if (update_interval < 0.0)
update_interval = 0.0;
} else {
@ -1089,7 +1087,7 @@ REF_SetReference(int stratum,
void
REF_SetManualReference
(
struct timeval *ref_time,
struct timespec *ref_time,
double offset,
double frequency,
double skew
@ -1108,7 +1106,7 @@ void
REF_SetUnsynchronised(void)
{
/* Variables required for logging to statistics log */
struct timeval now, now_raw;
struct timespec now, now_raw;
double uncorrected_offset;
assert(initialised);
@ -1121,7 +1119,7 @@ REF_SetUnsynchronised(void)
LCL_ReadRawTime(&now_raw);
LCL_GetOffsetCorrection(&now_raw, &uncorrected_offset, NULL);
UTI_AddDoubleToTimeval(&now_raw, uncorrected_offset, &now);
UTI_AddDoubleToTimespec(&now_raw, uncorrected_offset, &now);
if (fb_drifts) {
schedule_fb_drift(&now);
@ -1149,12 +1147,12 @@ REF_SetUnsynchronised(void)
void
REF_GetReferenceParams
(
struct timeval *local_time,
struct timespec *local_time,
int *is_synchronised,
NTP_Leap *leap_status,
int *stratum,
uint32_t *ref_id,
struct timeval *ref_time,
struct timespec *ref_time,
double *root_delay,
double *root_dispersion
)
@ -1164,7 +1162,7 @@ REF_GetReferenceParams
assert(initialised);
if (are_we_synchronised) {
UTI_DiffTimevalsToDouble(&elapsed, local_time, &our_ref_time);
UTI_DiffTimespecsToDouble(&elapsed, local_time, &our_ref_time);
dispersion = our_root_dispersion +
(our_skew + fabs(our_residual_freq) + LCL_GetMaxClockError()) * elapsed;
} else {
@ -1215,7 +1213,7 @@ REF_GetReferenceParams
*leap_status = LEAP_Unsynchronised;
*stratum = NTP_MAX_STRATUM;
*ref_id = NTP_REFID_UNSYNC;
ref_time->tv_sec = ref_time->tv_usec = 0;
UTI_ZeroTimespec(ref_time);
/* These values seem to be standard for a client, and
any peer or client of ours will ignore them anyway because
we don't claim to be synchronised */
@ -1230,7 +1228,7 @@ REF_GetReferenceParams
int
REF_GetOurStratum(void)
{
struct timeval now_cooked, ref_time;
struct timespec now_cooked, ref_time;
int synchronised, stratum;
NTP_Leap leap_status;
uint32_t ref_id;
@ -1303,7 +1301,7 @@ REF_DisableLocal(void)
int REF_IsLeapSecondClose(void)
{
struct timeval now, now_raw;
struct timespec now, now_raw;
time_t t;
if (!our_leap_sec)
@ -1327,13 +1325,13 @@ int REF_IsLeapSecondClose(void)
void
REF_GetTrackingReport(RPT_TrackingReport *rep)
{
struct timeval now_raw, now_cooked;
struct timespec now_raw, now_cooked;
double correction;
int synchronised;
LCL_ReadRawTime(&now_raw);
LCL_GetOffsetCorrection(&now_raw, &correction, NULL);
UTI_AddDoubleToTimeval(&now_raw, correction, &now_cooked);
UTI_AddDoubleToTimespec(&now_raw, correction, &now_cooked);
REF_GetReferenceParams(&now_cooked, &synchronised,
&rep->leap_status, &rep->stratum,

View file

@ -99,12 +99,12 @@ extern REF_LeapMode REF_GetLeapMode(void);
extern void REF_GetReferenceParams
(
struct timeval *local_time,
struct timespec *local_time,
int *is_synchronised,
NTP_Leap *leap,
int *stratum,
uint32_t *ref_id,
struct timeval *ref_time,
struct timespec *ref_time,
double *root_delay,
double *root_dispersion
);
@ -140,7 +140,7 @@ extern void REF_SetReference
int combined_sources,
uint32_t ref_id,
IPAddr *ref_ip,
struct timeval *ref_time,
struct timespec *ref_time,
double offset,
double offset_sd,
double frequency,
@ -151,7 +151,7 @@ extern void REF_SetReference
extern void REF_SetManualReference
(
struct timeval *ref_time,
struct timespec *ref_time,
double offset,
double frequency,
double skew

View file

@ -53,7 +53,7 @@ typedef struct {
IPAddr ip_addr;
int stratum;
NTP_Leap leap_status;
struct timeval ref_time;
struct timespec ref_time;
double current_correction;
double last_offset;
double rms_offset;
@ -79,7 +79,7 @@ typedef struct {
} RPT_SourcestatsReport;
typedef struct {
struct timeval ref_time;
struct timespec ref_time;
unsigned short n_samples;
unsigned short n_runs;
unsigned long span_seconds;
@ -109,7 +109,7 @@ typedef struct {
} RPT_ServerStatsReport;
typedef struct {
struct timeval when;
struct timespec when;
double slewed_offset;
double orig_offset;
double residual;

2
rtc.c
View file

@ -98,7 +98,7 @@ get_driftfile_time(void)
static void
apply_driftfile_time(time_t t)
{
struct timeval now;
struct timespec now;
LCL_ReadCookedTime(&now, NULL);

View file

@ -92,9 +92,8 @@ static double *rtc_trim = NULL;
static time_t rtc_ref;
/* System clock (gettimeofday) samples associated with the above
samples. */
static struct timeval *system_times = NULL;
/* System clock samples associated with the above samples. */
static struct timespec *system_times = NULL;
/* Number of samples currently stored. */
static int n_samples;
@ -170,7 +169,7 @@ discard_samples(int new_first)
memmove(rtc_sec, rtc_sec + new_first, n_to_save * sizeof(time_t));
memmove(rtc_trim, rtc_trim + new_first, n_to_save * sizeof(double));
memmove(system_times, system_times + new_first, n_to_save * sizeof(struct timeval));
memmove(system_times, system_times + new_first, n_to_save * sizeof(struct timespec));
n_samples = n_to_save;
}
@ -180,7 +179,7 @@ discard_samples(int new_first)
#define NEW_FIRST_WHEN_FULL 4
static void
accumulate_sample(time_t rtc, struct timeval *sys)
accumulate_sample(time_t rtc, struct timespec *sys)
{
if (n_samples == MAX_SAMPLES) {
@ -225,7 +224,7 @@ run_regression(int new_sample,
for (i=0; i<n_samples; i++) {
rtc_rel[i] = rtc_trim[i] + (double)(rtc_sec[i] - rtc_ref);
offsets[i] = ((double) (rtc_ref - system_times[i].tv_sec) -
(1.0e-6 * (double) system_times[i].tv_usec) +
(1.0e-9 * system_times[i].tv_nsec) +
rtc_rel[i]);
}
@ -262,7 +261,7 @@ run_regression(int new_sample,
static void
slew_samples
(struct timeval *raw, struct timeval *cooked,
(struct timespec *raw, struct timespec *cooked,
double dfreq,
double doffset,
LCL_ChangeType change_type,
@ -278,7 +277,7 @@ slew_samples
}
for (i=0; i<n_samples; i++) {
UTI_AdjustTimeval(system_times + i, cooked, system_times + i, &delta_time,
UTI_AdjustTimespec(system_times + i, cooked, system_times + i, &delta_time,
dfreq, doffset);
}
@ -534,7 +533,7 @@ RTC_Linux_Initialise(void)
{
rtc_sec = MallocArray(time_t, MAX_SAMPLES);
rtc_trim = MallocArray(double, MAX_SAMPLES);
system_times = MallocArray(struct timeval, MAX_SAMPLES);
system_times = MallocArray(struct timespec, MAX_SAMPLES);
/* Setup details depending on configuration options */
setup_config();
@ -758,7 +757,7 @@ maybe_autotrim(void)
/* ================================================== */
static void
process_reading(time_t rtc_time, struct timeval *system_time)
process_reading(time_t rtc_time, struct timespec *system_time)
{
double rtc_fast;
@ -791,7 +790,7 @@ process_reading(time_t rtc_time, struct timeval *system_time)
if (logfileid != -1) {
rtc_fast = (double)(rtc_time - system_time->tv_sec) - 1.0e-6 * (double) system_time->tv_usec;
rtc_fast = (rtc_time - system_time->tv_sec) - 1.0e-9 * system_time->tv_nsec;
LOG_FileWrite(logfileid, "%s %14.6f %1d %14.6f %12.3f %2d %2d %4d",
UTI_TimeToLogForm(system_time->tv_sec),
@ -809,7 +808,7 @@ read_from_device(int fd_, int event, void *any)
{
int status;
unsigned long data;
struct timeval sys_time;
struct timespec sys_time;
struct rtc_time rtc_raw;
struct tm rtc_tm;
time_t rtc_t;
@ -849,7 +848,7 @@ read_from_device(int fd_, int event, void *any)
goto turn_off_interrupt;
}
/* Convert RTC time into a struct timeval */
/* Convert RTC time into a struct timespec */
rtc_tm.tm_sec = rtc_raw.tm_sec;
rtc_tm.tm_min = rtc_raw.tm_min;
rtc_tm.tm_hour = rtc_raw.tm_hour;
@ -978,7 +977,7 @@ RTC_Linux_TimePreInit(time_t driftfile_time)
struct tm rtc_tm;
time_t rtc_t;
double accumulated_error, sys_offset;
struct timeval new_sys_time, old_sys_time;
struct timespec new_sys_time, old_sys_time;
coefs_file_name = CNF_GetRtcFile();
@ -1032,16 +1031,16 @@ RTC_Linux_TimePreInit(time_t driftfile_time)
new_sys_time.tv_sec = rtc_t;
/* Average error in the RTC reading */
new_sys_time.tv_usec = 500000;
new_sys_time.tv_nsec = 500000000;
UTI_AddDoubleToTimeval(&new_sys_time, -accumulated_error, &new_sys_time);
UTI_AddDoubleToTimespec(&new_sys_time, -accumulated_error, &new_sys_time);
if (new_sys_time.tv_sec < driftfile_time) {
LOG(LOGS_WARN, LOGF_RtcLinux, "RTC time before last driftfile modification (ignored)");
return 0;
}
UTI_DiffTimevalsToDouble(&sys_offset, &old_sys_time, &new_sys_time);
UTI_DiffTimespecsToDouble(&sys_offset, &old_sys_time, &new_sys_time);
/* Set system time only if the step is larger than 1 second */
if (fabs(sys_offset) >= 1.0) {
@ -1064,7 +1063,7 @@ int
RTC_Linux_GetReport(RPT_RTC_Report *report)
{
report->ref_time.tv_sec = coef_ref_time;
report->ref_time.tv_usec = 0;
report->ref_time.tv_nsec = 0;
report->n_samples = n_samples;
report->n_runs = n_runs;
if (n_samples > 1) {
@ -1083,8 +1082,7 @@ RTC_Linux_GetReport(RPT_RTC_Report *report)
int
RTC_Linux_Trim(void)
{
struct timeval now;
struct timespec now;
/* Remember the slope coefficient - we won't be able to determine a
good one in a few seconds when we determine the new offset! */
@ -1114,7 +1112,7 @@ RTC_Linux_Trim(void)
/* Estimate the offset in case writertc is called or chronyd
is terminated during rapid sampling */
coef_seconds_fast = -now.tv_usec / 1e6 + 0.5;
coef_seconds_fast = -now.tv_nsec / 1.0e9 + 0.5;
coef_ref_time = now.tv_sec;
/* And start rapid sampling, interrupts on now */

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

View file

@ -61,10 +61,10 @@ extern void SCH_RemoveFileHandler(int fd);
extern void SCH_SetFileHandlerEvents(int fd, int events);
/* Get the time stamp taken after a file descriptor became ready or a timeout expired */
extern void SCH_GetLastEventTime(struct timeval *cooked, double *err, struct timeval *raw);
extern void SCH_GetLastEventTime(struct timespec *cooked, double *err, struct timespec *raw);
/* This queues a timeout to elapse at a given (raw) local time */
extern SCH_TimeoutID SCH_AddTimeout(struct timeval *tv, SCH_TimeoutHandler, SCH_ArbitraryArgument);
extern SCH_TimeoutID SCH_AddTimeout(struct timespec *ts, SCH_TimeoutHandler handler, SCH_ArbitraryArgument arg);
/* This queues a timeout to elapse at a given delta time relative to the current (raw) time */
extern SCH_TimeoutID SCH_AddTimeoutByDelay(double delay, SCH_TimeoutHandler, SCH_ArbitraryArgument);

View file

@ -93,17 +93,17 @@ static double max_freq;
/* Frequency offset, time offset and the time of the last smoothing update */
static double smooth_freq;
static double smooth_offset;
static struct timeval last_update;
static struct timespec last_update;
static void
get_smoothing(struct timeval *now, double *poffset, double *pfreq,
get_smoothing(struct timespec *now, double *poffset, double *pfreq,
double *pwander)
{
double elapsed, length, offset, freq, wander;
int i;
UTI_DiffTimevalsToDouble(&elapsed, now, &last_update);
UTI_DiffTimespecsToDouble(&elapsed, now, &last_update);
offset = smooth_offset;
freq = smooth_freq;
@ -195,7 +195,7 @@ update_stages(void)
}
static void
update_smoothing(struct timeval *now, double offset, double freq)
update_smoothing(struct timespec *now, double offset, double freq)
{
/* Don't accept offset/frequency until the clock has stabilized */
if (locked) {
@ -215,7 +215,7 @@ update_smoothing(struct timeval *now, double offset, double freq)
}
static void
handle_slew(struct timeval *raw, struct timeval *cooked, double dfreq,
handle_slew(struct timespec *raw, struct timespec *cooked, double dfreq,
double doffset, LCL_ChangeType change_type, void *anything)
{
double delta;
@ -227,7 +227,7 @@ handle_slew(struct timeval *raw, struct timeval *cooked, double dfreq,
update_smoothing(cooked, doffset, dfreq);
}
UTI_AdjustTimeval(&last_update, cooked, &last_update, &delta, dfreq, doffset);
UTI_AdjustTimespec(&last_update, cooked, &last_update, &delta, dfreq, doffset);
}
void SMT_Initialise(void)
@ -258,7 +258,7 @@ int SMT_IsEnabled(void)
}
double
SMT_GetOffset(struct timeval *now)
SMT_GetOffset(struct timespec *now)
{
double offset, freq;
@ -271,7 +271,7 @@ SMT_GetOffset(struct timeval *now)
}
void
SMT_Activate(struct timeval *now)
SMT_Activate(struct timespec *now)
{
if (!enabled || !locked)
return;
@ -283,7 +283,7 @@ SMT_Activate(struct timeval *now)
}
void
SMT_Reset(struct timeval *now)
SMT_Reset(struct timespec *now)
{
int i;
@ -299,7 +299,7 @@ SMT_Reset(struct timeval *now)
}
void
SMT_Leap(struct timeval *now, int leap)
SMT_Leap(struct timespec *now, int leap)
{
/* When the leap-only mode is disabled, the leap second will be accumulated
in handle_slew() as a normal offset */
@ -310,7 +310,7 @@ SMT_Leap(struct timeval *now, int leap)
}
int
SMT_GetSmoothingReport(RPT_SmoothingReport *report, struct timeval *now)
SMT_GetSmoothingReport(RPT_SmoothingReport *report, struct timespec *now)
{
double length, elapsed;
int i;
@ -327,7 +327,7 @@ SMT_GetSmoothingReport(RPT_SmoothingReport *report, struct timeval *now)
report->freq_ppm *= -1.0e6;
report->wander_ppm *= -1.0e6;
UTI_DiffTimevalsToDouble(&elapsed, now, &last_update);
UTI_DiffTimespecsToDouble(&elapsed, now, &last_update);
if (!locked && elapsed >= 0.0) {
for (i = 0, length = 0.0; i < NUM_STAGES; i++)
length += stages[i].length;

View file

@ -35,14 +35,14 @@ extern void SMT_Finalise(void);
extern int SMT_IsEnabled(void);
extern double SMT_GetOffset(struct timeval *now);
extern double SMT_GetOffset(struct timespec *now);
extern void SMT_Activate(struct timeval *now);
extern void SMT_Activate(struct timespec *now);
extern void SMT_Reset(struct timeval *now);
extern void SMT_Reset(struct timespec *now);
extern void SMT_Leap(struct timeval *now, int leap);
extern void SMT_Leap(struct timespec *now, int leap);
extern int SMT_GetSmoothingReport(RPT_SmoothingReport *report, struct timeval *now);
extern int SMT_GetSmoothingReport(RPT_SmoothingReport *report, struct timespec *now);
#endif

View file

@ -166,7 +166,7 @@ static double combine_limit;
/* Forward prototype */
static void
slew_sources(struct timeval *raw, struct timeval *cooked, double dfreq,
slew_sources(struct timespec *raw, struct timespec *cooked, double dfreq,
double doffset, LCL_ChangeType change_type, void *anything);
static void
add_dispersion(double dispersion, void *anything);
@ -341,7 +341,7 @@ void SRC_GetFrequencyRange(SRC_Instance instance, double *lo, double *hi)
void SRC_AccumulateSample
(SRC_Instance inst,
struct timeval *sample_time,
struct timespec *sample_time,
double offset,
double peer_delay,
double peer_dispersion,
@ -356,7 +356,8 @@ void SRC_AccumulateSample
inst->leap_status = leap_status;
DEBUG_LOG(LOGF_Sources, "ip=[%s] t=%s ofs=%f del=%f disp=%f str=%d",
source_to_string(inst), UTI_TimevalToString(sample_time), -offset, root_delay, root_dispersion, stratum);
source_to_string(inst), UTI_TimespecToString(sample_time), -offset,
root_delay, root_dispersion, stratum);
if (REF_IsLeapSecondClose()) {
LOG(LOGS_INFO, LOGF_Sources, "Dropping sample around leap second");
@ -513,10 +514,10 @@ mark_ok_sources(SRC_Status status)
/* ================================================== */
static int
combine_sources(int n_sel_sources, struct timeval *ref_time, double *offset,
combine_sources(int n_sel_sources, struct timespec *ref_time, double *offset,
double *offset_sd, double *frequency, double *skew)
{
struct timeval src_ref_time;
struct timespec src_ref_time;
double src_offset, src_offset_sd, src_frequency, src_skew;
double src_root_delay, src_root_dispersion, sel_src_distance, elapsed;
double offset_weight, sum_offset_weight, sum_offset, sum2_offset_sd;
@ -563,7 +564,7 @@ combine_sources(int n_sel_sources, struct timeval *ref_time, double *offset,
if (sources[index]->status == SRC_OK)
sources[index]->status = SRC_UNSELECTED;
UTI_DiffTimevalsToDouble(&elapsed, ref_time, &src_ref_time);
UTI_DiffTimespecsToDouble(&elapsed, ref_time, &src_ref_time);
src_offset += elapsed * src_frequency;
offset_weight = 1.0 / sources[index]->sel_info.root_distance;
frequency_weight = 1.0 / src_skew;
@ -603,7 +604,7 @@ void
SRC_SelectSource(SRC_Instance updated_inst)
{
struct SelectInfo *si;
struct timeval now, ref_time;
struct timespec now, ref_time;
int i, j, j1, j2, index, sel_prefer, n_endpoints, n_sel_sources;
int n_badstats_sources, max_sel_reach, max_badstat_reach, sel_req_source;
int depth, best_depth, trust_depth, best_trust_depth;
@ -1097,7 +1098,7 @@ SRC_SetReselectDistance(double distance)
/* ================================================== */
double
SRC_PredictOffset(SRC_Instance inst, struct timeval *when)
SRC_PredictOffset(SRC_Instance inst, struct timespec *when)
{
return SST_PredictOffset(inst->stats, when);
}
@ -1114,7 +1115,7 @@ SRC_MinRoundTripDelay(SRC_Instance inst)
int
SRC_IsGoodSample(SRC_Instance inst, double offset, double delay,
double max_delay_dev_ratio, double clock_error, struct timeval *when)
double max_delay_dev_ratio, double clock_error, struct timespec *when)
{
return SST_IsGoodSample(inst->stats, offset, delay, max_delay_dev_ratio,
clock_error, when);
@ -1128,12 +1129,8 @@ SRC_IsGoodSample(SRC_Instance inst, double offset, double delay,
the new regime. */
static void
slew_sources(struct timeval *raw,
struct timeval *cooked,
double dfreq,
double doffset,
LCL_ChangeType change_type,
void *anything)
slew_sources(struct timespec *raw, struct timespec *cooked, double dfreq,
double doffset, LCL_ChangeType change_type, void *anything)
{
int i;
@ -1286,7 +1283,7 @@ SRC_ActiveSources(void)
/* ================================================== */
int
SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
SRC_ReportSource(int index, RPT_SourceReport *report, struct timespec *now)
{
SRC_Instance src;
if ((index >= n_sources) || (index < 0)) {
@ -1341,7 +1338,7 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
/* ================================================== */
int
SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timeval *now)
SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timespec *now)
{
SRC_Instance src;

View file

@ -114,7 +114,7 @@ extern void SRC_GetFrequencyRange(SRC_Instance instance, double *lo, double *hi)
*/
extern void SRC_AccumulateSample(SRC_Instance instance, struct timeval *sample_time, double offset, double peer_delay, double peer_dispersion, double root_delay, double root_dispersion, int stratum, NTP_Leap leap_status);
extern void SRC_AccumulateSample(SRC_Instance instance, struct timespec *sample_time, double offset, double peer_delay, double peer_dispersion, double root_delay, double root_dispersion, int stratum, NTP_Leap leap_status);
/* This routine sets the source as receiving reachability updates */
extern void SRC_SetActive(SRC_Instance inst);
@ -146,7 +146,7 @@ extern void SRC_SetReselectDistance(double distance);
/* Predict the offset of the local clock relative to a given source at
a given local cooked time. Positive indicates local clock is FAST
relative to reference. */
extern double SRC_PredictOffset(SRC_Instance inst, struct timeval *when);
extern double SRC_PredictOffset(SRC_Instance inst, struct timespec *when);
/* Return the minimum peer delay amongst the previous samples
currently held in the register */
@ -154,7 +154,7 @@ extern double SRC_MinRoundTripDelay(SRC_Instance inst);
/* This routine determines if a new sample is good enough that it should be
accumulated */
extern int SRC_IsGoodSample(SRC_Instance inst, double offset, double delay, double max_delay_dev_ratio, double clock_error, struct timeval *when);
extern int SRC_IsGoodSample(SRC_Instance inst, double offset, double delay, double max_delay_dev_ratio, double clock_error, struct timespec *when);
extern void SRC_DumpSources(void);
@ -164,9 +164,9 @@ extern int SRC_IsSyncPeer(SRC_Instance inst);
extern int SRC_IsReachable(SRC_Instance inst);
extern int SRC_ReadNumberOfSources(void);
extern int SRC_ActiveSources(void);
extern int SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now);
extern int SRC_ReportSource(int index, RPT_SourceReport *report, struct timespec *now);
extern int SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timeval *now);
extern int SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timespec *now);
extern SRC_Type SRC_GetType(int index);

View file

@ -105,7 +105,7 @@ struct SST_Stats_Record {
/* This is the estimated offset (+ve => local fast) at a particular time */
double estimated_offset;
double estimated_offset_sd;
struct timeval offset_time;
struct timespec offset_time;
/* Number of runs of the same sign amongst the residuals */
int nruns;
@ -133,7 +133,7 @@ struct SST_Stats_Record {
/* This array contains the sample epochs, in terms of the local
clock. */
struct timeval sample_times[MAX_SAMPLES * REGRESS_RUNS_RATIO];
struct timespec sample_times[MAX_SAMPLES * REGRESS_RUNS_RATIO];
/* This is an array of offsets, in seconds, corresponding to the
sample times. In this module, we use the convention that
@ -234,8 +234,7 @@ SST_ResetInstance(SST_Stats inst)
inst->skew = 2000.0e-6;
inst->estimated_offset = 0.0;
inst->estimated_offset_sd = 86400.0; /* Assume it's at least within a day! */
inst->offset_time.tv_sec = 0;
inst->offset_time.tv_usec = 0;
UTI_ZeroTimespec(&inst->offset_time);
inst->variance = 16.0;
inst->nruns = 0;
inst->asymmetry_run = 0;
@ -275,7 +274,7 @@ prune_register(SST_Stats inst, int new_oldest)
/* ================================================== */
void
SST_AccumulateSample(SST_Stats inst, struct timeval *sample_time,
SST_AccumulateSample(SST_Stats inst, struct timespec *sample_time,
double offset,
double peer_delay, double peer_dispersion,
double root_delay, double root_dispersion,
@ -291,7 +290,7 @@ SST_AccumulateSample(SST_Stats inst, struct timeval *sample_time,
/* Make sure it's newer than the last sample */
if (inst->n_samples &&
UTI_CompareTimevals(&inst->sample_times[inst->last_sample], sample_time) >= 0) {
UTI_CompareTimespecs(&inst->sample_times[inst->last_sample], sample_time) >= 0) {
LOG(LOGS_WARN, LOGF_SourceStats, "Out of order sample detected, discarding history for %s",
inst->ip_addr ? UTI_IPToString(inst->ip_addr) : UTI_RefidToString(inst->refid));
SST_ResetInstance(inst);
@ -345,14 +344,14 @@ get_buf_index(SST_Stats inst, int i)
static void
convert_to_intervals(SST_Stats inst, double *times_back)
{
struct timeval *newest_tv;
struct timespec *ts;
int i;
newest_tv = &(inst->sample_times[inst->last_sample]);
ts = &inst->sample_times[inst->last_sample];
for (i = -inst->runs_samples; i < inst->n_samples; i++) {
/* The entries in times_back[] should end up negative */
UTI_DiffTimevalsToDouble(&times_back[i],
&inst->sample_times[get_runsbuf_index(inst, i)], newest_tv);
UTI_DiffTimespecsToDouble(&times_back[i],
&inst->sample_times[get_runsbuf_index(inst, i)], ts);
}
}
@ -601,7 +600,7 @@ SST_GetFrequencyRange(SST_Stats inst,
/* ================================================== */
void
SST_GetSelectionData(SST_Stats inst, struct timeval *now,
SST_GetSelectionData(SST_Stats inst, struct timespec *now,
int *stratum,
double *offset_lo_limit,
double *offset_hi_limit,
@ -625,7 +624,7 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
*stratum = inst->strata[get_buf_index(inst, inst->n_samples - 1)];
*variance = inst->variance;
UTI_DiffTimevalsToDouble(&sample_elapsed, now, &inst->sample_times[i]);
UTI_DiffTimespecsToDouble(&sample_elapsed, now, &inst->sample_times[i]);
offset = inst->offsets[i] + sample_elapsed * inst->estimated_frequency;
*root_distance = 0.5 * inst->root_delays[j] +
inst->root_dispersions[j] + sample_elapsed * inst->skew;
@ -637,7 +636,7 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
double average_offset, elapsed;
int average_ok;
/* average_ok ignored for now */
UTI_DiffTimevalsToDouble(&elapsed, now, &(inst->offset_time));
UTI_DiffTimespecsToDouble(&elapsed, now, &(inst->offset_time));
average_offset = inst->estimated_offset + inst->estimated_frequency * elapsed;
if (fabs(average_offset - offset) <=
inst->peer_dispersions[j] + 0.5 * inst->peer_delays[i]) {
@ -648,9 +647,9 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
#endif
i = get_runsbuf_index(inst, 0);
UTI_DiffTimevalsToDouble(first_sample_ago, now, &inst->sample_times[i]);
UTI_DiffTimespecsToDouble(first_sample_ago, now, &inst->sample_times[i]);
i = get_runsbuf_index(inst, inst->n_samples - 1);
UTI_DiffTimevalsToDouble(last_sample_ago, now, &inst->sample_times[i]);
UTI_DiffTimespecsToDouble(last_sample_ago, now, &inst->sample_times[i]);
*select_ok = inst->regression_ok;
@ -662,7 +661,7 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
/* ================================================== */
void
SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
SST_GetTrackingData(SST_Stats inst, struct timespec *ref_time,
double *average_offset, double *offset_sd,
double *frequency, double *skew,
double *root_delay, double *root_dispersion)
@ -682,7 +681,7 @@ SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
*skew = inst->skew;
*root_delay = inst->root_delays[j];
UTI_DiffTimevalsToDouble(&elapsed_sample, &inst->offset_time, &inst->sample_times[i]);
UTI_DiffTimespecsToDouble(&elapsed_sample, &inst->offset_time, &inst->sample_times[i]);
*root_dispersion = inst->root_dispersions[j] + inst->skew * elapsed_sample;
DEBUG_LOG(LOGF_SourceStats, "n=%d freq=%f (%.3fppm) skew=%f (%.3fppm) avoff=%f offsd=%f disp=%f",
@ -693,11 +692,11 @@ SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
/* ================================================== */
void
SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffset)
SST_SlewSamples(SST_Stats inst, struct timespec *when, double dfreq, double doffset)
{
int m, i;
double delta_time;
struct timeval *sample, prev;
struct timespec *sample, prev;
double prev_offset, prev_freq;
if (!inst->n_samples)
@ -705,9 +704,9 @@ SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffs
for (m = -inst->runs_samples; m < inst->n_samples; m++) {
i = get_runsbuf_index(inst, m);
sample = &(inst->sample_times[i]);
sample = &inst->sample_times[i];
prev = *sample;
UTI_AdjustTimeval(sample, when, sample, &delta_time, dfreq, doffset);
UTI_AdjustTimespec(sample, when, sample, &delta_time, dfreq, doffset);
inst->offsets[i] += delta_time;
}
@ -715,14 +714,14 @@ SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffs
prev = inst->offset_time;
prev_offset = inst->estimated_offset;
prev_freq = inst->estimated_frequency;
UTI_AdjustTimeval(&(inst->offset_time), when, &(inst->offset_time),
UTI_AdjustTimespec(&inst->offset_time, when, &inst->offset_time,
&delta_time, dfreq, doffset);
inst->estimated_offset += delta_time;
inst->estimated_frequency = (inst->estimated_frequency - dfreq) / (1.0 - dfreq);
DEBUG_LOG(LOGF_SourceStats, "n=%d m=%d old_off_time=%s new=%s old_off=%f new_off=%f old_freq=%.3f new_freq=%.3f",
inst->n_samples, inst->runs_samples,
UTI_TimevalToString(&prev), UTI_TimevalToString(&(inst->offset_time)),
UTI_TimespecToString(&prev), UTI_TimespecToString(&inst->offset_time),
prev_offset, inst->estimated_offset,
1.0e6 * prev_freq, 1.0e6 * inst->estimated_frequency);
}
@ -744,7 +743,7 @@ SST_AddDispersion(SST_Stats inst, double dispersion)
/* ================================================== */
double
SST_PredictOffset(SST_Stats inst, struct timeval *when)
SST_PredictOffset(SST_Stats inst, struct timespec *when)
{
double elapsed;
@ -758,7 +757,7 @@ SST_PredictOffset(SST_Stats inst, struct timeval *when)
return 0.0;
}
} else {
UTI_DiffTimevalsToDouble(&elapsed, when, &inst->offset_time);
UTI_DiffTimespecsToDouble(&elapsed, when, &inst->offset_time);
return inst->estimated_offset + elapsed * inst->estimated_frequency;
}
@ -778,14 +777,14 @@ SST_MinRoundTripDelay(SST_Stats inst)
int
SST_IsGoodSample(SST_Stats inst, double offset, double delay,
double max_delay_dev_ratio, double clock_error, struct timeval *when)
double max_delay_dev_ratio, double clock_error, struct timespec *when)
{
double elapsed, allowed_increase, delay_increase;
if (inst->n_samples < 3)
return 1;
UTI_DiffTimevalsToDouble(&elapsed, when, &inst->offset_time);
UTI_DiffTimespecsToDouble(&elapsed, when, &inst->offset_time);
/* Require that the ratio of the increase in delay from the minimum to the
standard deviation is less than max_delay_dev_ratio. In the allowed
@ -829,7 +828,7 @@ SST_SaveToFile(SST_Stats inst, FILE *out)
fprintf(out, "%08lx %08lx %.6e %.6e %.6e %.6e %.6e %.6e %.6e %d\n",
(unsigned long) inst->sample_times[i].tv_sec,
(unsigned long) inst->sample_times[i].tv_usec,
(unsigned long)inst->sample_times[i].tv_nsec / 1000,
inst->offsets[i],
inst->orig_offsets[j],
inst->peer_delays[i],
@ -883,7 +882,8 @@ SST_LoadFromFile(SST_Stats inst, FILE *in)
/* This is the branch taken if the read is SUCCESSFUL */
inst->sample_times[i].tv_sec = sec;
inst->sample_times[i].tv_usec = usec;
inst->sample_times[i].tv_nsec = 1000 * usec;
UTI_NormaliseTimespec(&inst->sample_times[i]);
line_number++;
}
@ -906,10 +906,10 @@ SST_LoadFromFile(SST_Stats inst, FILE *in)
/* ================================================== */
void
SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now)
SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timespec *now)
{
int i, j;
struct timeval ago;
struct timespec ago;
if (inst->n_samples > 0) {
i = get_runsbuf_index(inst, inst->n_samples - 1);
@ -919,7 +919,7 @@ SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now
report->latest_meas_err = 0.5*inst->root_delays[j] + inst->root_dispersions[j];
report->stratum = inst->strata[j];
UTI_DiffTimevals(&ago, now, &inst->sample_times[i]);
UTI_DiffTimespecs(&ago, now, &inst->sample_times[i]);
report->latest_meas_ago = ago.tv_sec;
} else {
report->latest_meas_ago = (uint32_t)-1;
@ -941,7 +941,7 @@ SST_Samples(SST_Stats inst)
/* ================================================== */
void
SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct timeval *now)
SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct timespec *now)
{
double dspan;
double elapsed, sample_elapsed;
@ -953,15 +953,15 @@ SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct ti
if (inst->n_samples > 1) {
li = get_runsbuf_index(inst, inst->n_samples - 1);
lj = get_buf_index(inst, inst->n_samples - 1);
UTI_DiffTimevalsToDouble(&dspan, &inst->sample_times[li],
UTI_DiffTimespecsToDouble(&dspan, &inst->sample_times[li],
&inst->sample_times[get_runsbuf_index(inst, 0)]);
report->span_seconds = (unsigned long) (dspan + 0.5);
if (inst->n_samples > 3) {
UTI_DiffTimevalsToDouble(&elapsed, now, &inst->offset_time);
UTI_DiffTimespecsToDouble(&elapsed, now, &inst->offset_time);
bi = get_runsbuf_index(inst, inst->best_single_sample);
bj = get_buf_index(inst, inst->best_single_sample);
UTI_DiffTimevalsToDouble(&sample_elapsed, now, &inst->sample_times[bi]);
UTI_DiffTimespecsToDouble(&sample_elapsed, now, &inst->sample_times[bi]);
report->est_offset = inst->estimated_offset + elapsed * inst->estimated_frequency;
report->est_offset_err = (inst->estimated_offset_sd +
sample_elapsed * inst->skew +

View file

@ -61,7 +61,7 @@ extern void SST_SetRefid(SST_Stats inst, uint32_t refid, IPAddr *addr);
stratum is the stratum of the source from which the sample came.
*/
extern void SST_AccumulateSample(SST_Stats inst, struct timeval *sample_time, double offset, double peer_delay, double peer_dispersion, double root_delay, double root_dispersion, int stratum);
extern void SST_AccumulateSample(SST_Stats inst, struct timespec *sample_time, double offset, double peer_delay, double peer_dispersion, double root_delay, double root_dispersion, int stratum);
/* This function runs the linear regression operation on the data. It
finds the set of most recent samples that give the tightest
@ -77,7 +77,7 @@ extern void SST_GetFrequencyRange(SST_Stats inst, double *lo, double *hi);
/* Get data needed for selection */
extern void
SST_GetSelectionData(SST_Stats inst, struct timeval *now,
SST_GetSelectionData(SST_Stats inst, struct timespec *now,
int *stratum,
double *offset_lo_limit,
double *offset_hi_limit,
@ -89,7 +89,7 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
/* Get data needed when setting up tracking on this source */
extern void
SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
SST_GetTrackingData(SST_Stats inst, struct timespec *ref_time,
double *average_offset, double *offset_sd,
double *frequency, double *skew,
double *root_delay, double *root_dispersion);
@ -110,7 +110,7 @@ SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
*/
extern void SST_SlewSamples(SST_Stats inst, struct timeval *when, double dfreq, double doffset);
extern void SST_SlewSamples(SST_Stats inst, struct timespec *when, double dfreq, double doffset);
/* This routine is called when an indeterminate offset is introduced
into the local time. */
@ -119,7 +119,7 @@ extern void SST_AddDispersion(SST_Stats inst, double dispersion);
/* Predict the offset of the local clock relative to a given source at
a given local cooked time. Positive indicates local clock is FAST
relative to reference. */
extern double SST_PredictOffset(SST_Stats inst, struct timeval *when);
extern double SST_PredictOffset(SST_Stats inst, struct timespec *when);
/* Find the minimum round trip delay in the register */
extern double SST_MinRoundTripDelay(SST_Stats inst);
@ -127,15 +127,15 @@ extern double SST_MinRoundTripDelay(SST_Stats inst);
/* This routine determines if a new sample is good enough that it should be
accumulated */
extern int SST_IsGoodSample(SST_Stats inst, double offset, double delay,
double max_delay_dev_ratio, double clock_error, struct timeval *when);
double max_delay_dev_ratio, double clock_error, struct timespec *when);
extern void SST_SaveToFile(SST_Stats inst, FILE *out);
extern int SST_LoadFromFile(SST_Stats inst, FILE *in);
extern void SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now);
extern void SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timespec *now);
extern void SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct timeval *now);
extern void SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct timespec *now);
extern int SST_Samples(SST_Stats inst);

View file

@ -292,7 +292,7 @@ NSR_ModifyPolltarget(IPAddr *address, int new_poll_target)
}
void
NSR_ReportSource(RPT_SourceReport *report, struct timeval *now)
NSR_ReportSource(RPT_SourceReport *report, struct timespec *now)
{
memset(report, 0, sizeof (*report));
}
@ -362,7 +362,7 @@ RCL_StartRefclocks(void)
}
void
RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
RCL_ReportSource(RPT_SourceReport *report, struct timespec *now)
{
memset(report, 0, sizeof (*report));
}

View file

@ -71,7 +71,7 @@ static double offset_register;
static double slew_freq;
/* Time (raw) of last update of slewing frequency and offset */
static struct timeval slew_start;
static struct timespec slew_start;
/* Limits for the slew timeout */
#define MIN_SLEW_TIMEOUT 1.0
@ -106,7 +106,7 @@ static void update_slew(void);
/* Adjust slew_start on clock step */
static void
handle_step(struct timeval *raw, struct timeval *cooked, double dfreq,
handle_step(struct timespec *raw, struct timespec *cooked, double dfreq,
double doffset, LCL_ChangeType change_type, void *anything)
{
if (change_type == LCL_ChangeUnknownStep) {
@ -115,7 +115,7 @@ handle_step(struct timeval *raw, struct timeval *cooked, double dfreq,
offset_register = 0.0;
update_slew();
} else if (change_type == LCL_ChangeStep) {
UTI_AddDoubleToTimeval(&slew_start, -doffset, &slew_start);
UTI_AddDoubleToTimespec(&slew_start, -doffset, &slew_start);
}
}
@ -138,7 +138,7 @@ start_fastslew(void)
/* ================================================== */
static void
stop_fastslew(struct timeval *now)
stop_fastslew(struct timespec *now)
{
double corr;
@ -169,7 +169,7 @@ clamp_freq(double freq)
static void
update_slew(void)
{
struct timeval now, end_of_slew;
struct timespec now, end_of_slew;
double old_slew_freq, total_freq, corr_freq, duration;
/* Remove currently running timeout */
@ -178,7 +178,7 @@ update_slew(void)
LCL_ReadRawTime(&now);
/* Adjust the offset register by achieved slew */
UTI_DiffTimevalsToDouble(&duration, &now, &slew_start);
UTI_DiffTimespecsToDouble(&duration, &now, &slew_start);
offset_register -= slew_freq * duration;
stop_fastslew(&now);
@ -242,7 +242,7 @@ update_slew(void)
}
/* Restart timer for the next update */
UTI_AddDoubleToTimeval(&now, duration, &end_of_slew);
UTI_AddDoubleToTimespec(&now, duration, &end_of_slew);
slew_timeout_id = SCH_AddTimeout(&end_of_slew, handle_end_of_slew, NULL);
slew_start = now;
@ -294,12 +294,12 @@ accrue_offset(double offset, double corr_rate)
/* Determine the correction to generate the cooked time for given raw time */
static void
offset_convert(struct timeval *raw,
offset_convert(struct timespec *raw,
double *corr, double *err)
{
double duration, fastslew_corr, fastslew_err;
UTI_DiffTimevalsToDouble(&duration, raw, &slew_start);
UTI_DiffTimespecsToDouble(&duration, raw, &slew_start);
if (drv_get_offset_correction && fastslew_active) {
drv_get_offset_correction(raw, &fastslew_corr, &fastslew_err);
@ -324,19 +324,21 @@ offset_convert(struct timeval *raw,
static int
apply_step_offset(double offset)
{
struct timeval old_time, new_time;
struct timespec old_time, new_time;
struct timeval new_time_tv;
double err;
LCL_ReadRawTime(&old_time);
UTI_AddDoubleToTimeval(&old_time, -offset, &new_time);
UTI_AddDoubleToTimespec(&old_time, -offset, &new_time);
UTI_TimespecToTimeval(&new_time, &new_time_tv);
if (PRV_SetTime(&new_time, NULL) < 0) {
if (PRV_SetTime(&new_time_tv, NULL) < 0) {
DEBUG_LOG(LOGF_SysGeneric, "settimeofday() failed");
return 0;
}
LCL_ReadRawTime(&old_time);
UTI_DiffTimevalsToDouble(&err, &old_time, &new_time);
UTI_DiffTimespecsToDouble(&err, &old_time, &new_time);
lcl_InvokeDispersionNotifyHandlers(fabs(err));
@ -403,7 +405,7 @@ SYS_Generic_CompleteFreqDriver(double max_set_freq_ppm, double max_set_freq_dela
void
SYS_Generic_Finalise(void)
{
struct timeval now;
struct timespec now;
/* Must *NOT* leave a slew running - clock could drift way off
if the daemon is not restarted */

View file

@ -39,6 +39,7 @@
#include "sys_macosx.h"
#include "conf.h"
#include "local.h"
#include "localp.h"
#include "logging.h"
#include "sched.h"
@ -49,13 +50,13 @@
/* This register contains the number of seconds by which the local
clock was estimated to be fast of reference time at the epoch when
gettimeofday() returned T0 */
LCL_ReadRawTime() returned T0 */
static double offset_register;
/* This register contains the epoch to which the offset is referenced */
static struct timeval T0;
static struct timespec T0;
/* This register contains the current estimate of the system
frequency, in absolute (NOT ppm) */
@ -79,7 +80,7 @@ static double adjustment_requested;
static double drift_removal_interval;
static double current_drift_removal_interval;
static struct timeval Tdrift;
static struct timespec Tdrift;
/* weighting applied to error in calculating drift_removal_interval */
#define ERROR_WEIGHT (0.5)
@ -91,7 +92,7 @@ static struct timeval Tdrift;
/* RTC synchronisation - once an hour */
static struct timeval last_rtc_sync;
static struct timespec last_rtc_sync;
#define RTC_SYNC_INTERVAL (60 * 60.0)
/* ================================================== */
@ -107,9 +108,7 @@ clock_initialise(void)
drift_removal_interval = DRIFT_REMOVAL_INTERVAL;
current_drift_removal_interval = DRIFT_REMOVAL_INTERVAL;
if (gettimeofday(&T0, NULL) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
}
LCL_ReadRawTime(&T0);
Tdrift = T0;
last_rtc_sync = T0;
@ -135,21 +134,19 @@ static void
start_adjust(void)
{
struct timeval newadj, oldadj;
struct timeval T1;
struct timespec T1;
double elapsed, accrued_error, predicted_error, drift_removal_elapsed;
double adjust_required;
double rounding_error;
double old_adjust_remaining;
/* Determine the amount of error built up since the last adjustment */
if (gettimeofday(&T1, NULL) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
}
LCL_ReadRawTime(&T1);
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
UTI_DiffTimespecsToDouble(&elapsed, &T1, &T0);
accrued_error = elapsed * current_freq;
UTI_DiffTimevalsToDouble(&drift_removal_elapsed, &T1, &Tdrift);
UTI_DiffTimespecsToDouble(&drift_removal_elapsed, &T1, &Tdrift);
/* To allow for the clock being stepped either forward or backwards, clamp
the elapsed time to bounds [ 0.0, current_drift_removal_interval ] */
@ -184,7 +181,7 @@ start_adjust(void)
static void
stop_adjust(void)
{
struct timeval T1;
struct timespec T1;
struct timeval zeroadj, remadj;
double adjustment_remaining, adjustment_achieved;
double elapsed, elapsed_plus_adjust;
@ -196,11 +193,9 @@ stop_adjust(void)
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
}
if (gettimeofday(&T1, NULL) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
}
LCL_ReadRawTime(&T1);
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
UTI_DiffTimespecsToDouble(&elapsed, &T1, &T0);
UTI_TimevalToDouble(&remadj, &adjustment_remaining);
adjustment_achieved = adjustment_requested - adjustment_remaining;
@ -233,22 +228,22 @@ accrue_offset(double offset, double corr_rate)
static int
apply_step_offset(double offset)
{
struct timeval old_time, new_time, T1;
struct timespec old_time, new_time, T1;
struct timeval new_time_tv;
stop_adjust();
if (gettimeofday(&old_time, NULL) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
}
LCL_ReadRawTime(&old_time);
UTI_AddDoubleToTimeval(&old_time, -offset, &new_time);
UTI_AddDoubleToTimespec(&old_time, -offset, &new_time);
UTI_TimespecToTimeval(&new_time, &new_time_tv);
if (PRV_SetTime(&new_time, NULL) < 0) {
if (PRV_SetTime(&new_time_tv, NULL) < 0) {
DEBUG_LOG(LOGF_SysMacOSX, "settimeofday() failed");
return 0;
}
UTI_AddDoubleToTimeval(&T0, -offset, &T1);
UTI_AddDoubleToTimespec(&T0, -offset, &T1);
T0 = T1;
start_adjust();
@ -279,7 +274,7 @@ read_frequency(void)
/* ================================================== */
static void
get_offset_correction(struct timeval *raw,
get_offset_correction(struct timespec *raw,
double *corr, double *err)
{
stop_adjust();
@ -311,9 +306,7 @@ drift_removal_timeout(SCH_ArbitraryArgument not_used)
stop_adjust();
if (gettimeofday(&Tdrift, NULL) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
}
LCL_ReadRawTime(&Tdrift);
current_drift_removal_interval = drift_removal_interval;
@ -336,11 +329,11 @@ set_sync_status(int synchronised, double est_error, double max_error)
drift_removal_interval = MAX(drift_removal_interval, DRIFT_REMOVAL_INTERVAL);
} else {
if (CNF_GetRtcSync()) {
struct timeval now;
struct timespec now;
double rtc_sync_elapsed;
SCH_GetLastEventTime(NULL, NULL, &now);
UTI_DiffTimevalsToDouble(&rtc_sync_elapsed, &now, &last_rtc_sync);
UTI_DiffTimespecsToDouble(&rtc_sync_elapsed, &now, &last_rtc_sync);
if (fabs(rtc_sync_elapsed) >= RTC_SYNC_INTERVAL) {
/* update the RTC by applying a step of 0.0 secs */
apply_step_offset(0.0);

View file

@ -60,6 +60,7 @@ static void
accrue_offset(double offset, double corr_rate)
{
struct timeval newadj, oldadj;
double doldadj;
UTI_DoubleToTimeval(-offset, &newadj);
@ -67,9 +68,9 @@ accrue_offset(double offset, double corr_rate)
LOG_FATAL(LOGF_SysNetBSD, "adjtime() failed");
/* Add the old remaining adjustment if not zero */
UTI_TimevalToDouble(&oldadj, &offset);
if (offset != 0.0) {
UTI_AddDoubleToTimeval(&newadj, offset, &newadj);
UTI_TimevalToDouble(&oldadj, &doldadj);
if (doldadj != 0.0) {
UTI_DoubleToTimeval(-offset + doldadj, &newadj);
if (PRV_AdjustTime(&newadj, NULL) < 0)
LOG_FATAL(LOGF_SysNetBSD, "adjtime() failed");
}
@ -78,7 +79,7 @@ accrue_offset(double offset, double corr_rate)
/* ================================================== */
static void
get_offset_correction(struct timeval *raw,
get_offset_correction(struct timespec *raw,
double *corr, double *err)
{
struct timeval remadj;

View file

@ -95,7 +95,7 @@ read_timeout(void *arg)
DEBUG_LOG(LOGF_TempComp, "tempcomp updated to %f for %f", comp, temp);
if (logfileid != -1) {
struct timeval now;
struct timespec now;
LCL_ReadCookedTime(&now, NULL);
LOG_FileWrite(logfileid, "%s %11.4e %11.4e",

View file

@ -25,7 +25,7 @@ void
test_unit(void)
{
int i, j, index;
struct timeval tv;
struct timespec ts;
IPAddr ip;
char conf[][100] = {
"clientloglimit 10000",
@ -44,24 +44,24 @@ test_unit(void)
for (i = 0; i < 500; i++) {
DEBUG_LOG(0, "iteration %d", i);
tv.tv_sec = (time_t)random() & 0x0fffffff;
tv.tv_usec = 0;
ts.tv_sec = (time_t)random() & 0x0fffffff;
ts.tv_nsec = 0;
for (j = 0; j < 1000; j++) {
TST_GetRandomAddress(&ip, IPADDR_UNSPEC, i % 8 ? -1 : i / 8 % 9);
DEBUG_LOG(0, "address %s", UTI_IPToString(&ip));
if (random() % 2) {
index = CLG_LogNTPAccess(&ip, &tv);
index = CLG_LogNTPAccess(&ip, &ts);
TEST_CHECK(index >= 0);
CLG_LimitNTPResponseRate(index);
} else {
index = CLG_LogCommandAccess(&ip, &tv);
index = CLG_LogCommandAccess(&ip, &ts);
TEST_CHECK(index >= 0);
CLG_LimitCommandResponseRate(index);
}
UTI_AddDoubleToTimeval(&tv, (1 << random() % 14) / 100.0, &tv);
UTI_AddDoubleToTimespec(&ts, (1 << random() % 14) / 100.0, &ts);
}
}
@ -69,8 +69,8 @@ test_unit(void)
TEST_CHECK(ARR_GetSize(records) == 128);
for (i = j = 0; i < 10000; i++) {
tv.tv_sec += 1;
index = CLG_LogNTPAccess(&ip, &tv);
ts.tv_sec += 1;
index = CLG_LogNTPAccess(&ip, &ts);
TEST_CHECK(index >= 0);
if (!CLG_LimitNTPResponseRate(index))
j++;

View file

@ -29,7 +29,7 @@ test_unit(void)
IPAddr addr;
int i, j, k, l, samples, sel_options;
double offset, delay, disp;
struct timeval tv;
struct timespec ts;
CNF_Initialise(0);
LCL_Initialise();
@ -61,8 +61,8 @@ test_unit(void)
offset = TST_GetRandomDouble(-1.0, 1.0);
for (k = 0; k < samples; k++) {
SCH_GetLastEventTime(&tv, NULL, NULL);
UTI_AddDoubleToTimeval(&tv, TST_GetRandomDouble(k - samples, k - samples + 1), &tv);
SCH_GetLastEventTime(&ts, NULL, NULL);
UTI_AddDoubleToTimespec(&ts, TST_GetRandomDouble(k - samples, k - samples + 1), &ts);
offset += TST_GetRandomDouble(-1.0e-2, 1.0e-2);
delay = TST_GetRandomDouble(1.0e-6, 1.0e-1);
@ -71,7 +71,7 @@ test_unit(void)
DEBUG_LOG(0, "source %d sample %d offset %f delay %f disp %f", j, k,
offset, delay, disp);
SRC_AccumulateSample(srcs[j], &tv, offset, delay, disp, delay, disp,
SRC_AccumulateSample(srcs[j], &ts, offset, delay, disp, delay, disp,
1, LEAP_Normal);
}
@ -124,7 +124,7 @@ test_unit(void)
}
for (j = 0; j < sizeof (srcs) / sizeof (srcs[0]); j++) {
SRC_ReportSource(j, &report, &tv);
SRC_ReportSource(j, &report, &ts);
SRC_DestroyInstance(srcs[j]);
}
}

View file

@ -150,7 +150,7 @@ apply_step_offset(double offset)
}
static void
offset_convert(struct timeval *raw, double *corr, double *err)
offset_convert(struct timespec *raw, double *corr, double *err)
{
*corr = 0.0;
if (err)

254
util.c
View file

@ -34,6 +34,70 @@
#include "util.h"
#include "hash.h"
#define NSEC_PER_SEC 1000000000
/* ================================================== */
void
UTI_ZeroTimespec(struct timespec *ts)
{
ts->tv_sec = 0;
ts->tv_nsec = 0;
}
/* ================================================== */
void
UTI_TimevalToTimespec(struct timeval *tv, struct timespec *ts)
{
ts->tv_sec = tv->tv_sec;
ts->tv_nsec = 1000 * tv->tv_usec;
}
/* ================================================== */
void
UTI_TimespecToTimeval(struct timespec *ts, struct timeval *tv)
{
tv->tv_sec = ts->tv_sec;
tv->tv_usec = ts->tv_nsec / 1000;
}
/* ================================================== */
void
UTI_TimespecToDouble(struct timespec *ts, double *d)
{
*d = ts->tv_sec + 1.0e-9 * ts->tv_nsec;
}
/* ================================================== */
void
UTI_DoubleToTimespec(double d, struct timespec *ts)
{
ts->tv_sec = d;
ts->tv_nsec = 1.0e9 * (d - ts->tv_sec);
UTI_NormaliseTimespec(ts);
}
/* ================================================== */
void
UTI_NormaliseTimespec(struct timespec *ts)
{
if (ts->tv_nsec >= NSEC_PER_SEC || ts->tv_nsec < 0) {
ts->tv_sec += ts->tv_nsec / NSEC_PER_SEC;
ts->tv_nsec = ts->tv_nsec % NSEC_PER_SEC;
/* If seconds are negative nanoseconds would end up negative too */
if (ts->tv_nsec < 0) {
ts->tv_sec--;
ts->tv_nsec += NSEC_PER_SEC;
}
}
}
/* ================================================== */
void
@ -60,26 +124,6 @@ UTI_DoubleToTimeval(double a, struct timeval *b)
/* ================================================== */
int
UTI_CompareTimevals(struct timeval *a, struct timeval *b)
{
if (a->tv_sec < b->tv_sec) {
return -1;
} else if (a->tv_sec > b->tv_sec) {
return +1;
} else {
if (a->tv_usec < b->tv_usec) {
return -1;
} else if (a->tv_usec > b->tv_usec) {
return +1;
} else {
return 0;
}
}
}
/* ================================================== */
void
UTI_NormaliseTimeval(struct timeval *x)
{
@ -99,100 +143,73 @@ UTI_NormaliseTimeval(struct timeval *x)
/* ================================================== */
void
UTI_DiffTimevals(struct timeval *result,
struct timeval *a,
struct timeval *b)
int
UTI_CompareTimespecs(struct timespec *a, struct timespec *b)
{
result->tv_sec = a->tv_sec - b->tv_sec;
result->tv_usec = a->tv_usec - b->tv_usec;
if (a->tv_sec < b->tv_sec)
return -1;
if (a->tv_sec > b->tv_sec)
return 1;
if (a->tv_nsec < b->tv_nsec)
return -1;
if (a->tv_nsec > b->tv_nsec)
return 1;
return 0;
}
/* Correct microseconds field to bring it into the range
(0,1000000) */
/* ================================================== */
UTI_NormaliseTimeval(result); /* JGH */
void
UTI_DiffTimespecs(struct timespec *result, struct timespec *a, struct timespec *b)
{
result->tv_sec = a->tv_sec - b->tv_sec;
result->tv_nsec = a->tv_nsec - b->tv_nsec;
UTI_NormaliseTimespec(result);
}
/* ================================================== */
/* Calculate result = a - b and return as a double */
void
UTI_DiffTimevalsToDouble(double *result,
struct timeval *a,
struct timeval *b)
UTI_DiffTimespecsToDouble(double *result, struct timespec *a, struct timespec *b)
{
*result = (double)(a->tv_sec - b->tv_sec) +
(double)(a->tv_usec - b->tv_usec) * 1.0e-6;
*result = (a->tv_sec - b->tv_sec) + 1.0e-9 * (a->tv_nsec - b->tv_nsec);
}
/* ================================================== */
void
UTI_AddDoubleToTimeval(struct timeval *start,
double increment,
struct timeval *end)
UTI_AddDoubleToTimespec(struct timespec *start, double increment, struct timespec *end)
{
long int_part, frac_part;
time_t int_part;
/* Don't want to do this by using (long)(1000000 * increment), since
that will only cope with increments up to +/- 2148 seconds, which
is too marginal here. */
int_part = (long) increment;
increment = (increment - int_part) * 1.0e6;
frac_part = (long) (increment > 0.0 ? increment + 0.5 : increment - 0.5);
end->tv_sec = int_part + start->tv_sec;
end->tv_usec = frac_part + start->tv_usec;
UTI_NormaliseTimeval(end);
int_part = increment;
end->tv_sec = start->tv_sec + int_part;
end->tv_nsec = start->tv_nsec + 1.0e9 * (increment - int_part);
UTI_NormaliseTimespec(end);
}
/* ================================================== */
/* Calculate the average and difference (as a double) of two timevals */
/* Calculate the average and difference (as a double) of two timespecs */
void
UTI_AverageDiffTimevals (struct timeval *earlier,
struct timeval *later,
struct timeval *average,
double *diff)
UTI_AverageDiffTimespecs(struct timespec *earlier, struct timespec *later,
struct timespec *average, double *diff)
{
struct timeval tvdiff;
struct timeval tvhalf;
UTI_DiffTimevals(&tvdiff, later, earlier);
*diff = (double)tvdiff.tv_sec + 1.0e-6 * (double)tvdiff.tv_usec;
if (*diff < 0.0) {
/* Either there's a bug elsewhere causing 'earlier' and 'later' to
be backwards, or something wierd has happened. Maybe when we
change the frequency on Linux? */
/* Assume the required behaviour is to treat it as zero */
*diff = 0.0;
}
tvhalf.tv_sec = tvdiff.tv_sec / 2;
tvhalf.tv_usec = tvdiff.tv_usec / 2 + (tvdiff.tv_sec % 2) * 500000; /* JGH */
average->tv_sec = earlier->tv_sec + tvhalf.tv_sec;
average->tv_usec = earlier->tv_usec + tvhalf.tv_usec;
/* Bring into range */
UTI_NormaliseTimeval(average);
}
UTI_DiffTimespecsToDouble(diff, later, earlier);
UTI_AddDoubleToTimespec(earlier, *diff / 2.0, average);
}
/* ================================================== */
void
UTI_AddDiffToTimeval(struct timeval *a, struct timeval *b,
struct timeval *c, struct timeval *result)
UTI_AddDiffToTimespec(struct timespec *a, struct timespec *b,
struct timespec *c, struct timespec *result)
{
double diff;
UTI_DiffTimevalsToDouble(&diff, a, b);
UTI_AddDoubleToTimeval(c, diff, result);
UTI_DiffTimespecsToDouble(&diff, a, b);
UTI_AddDoubleToTimespec(c, diff, result);
}
/* ================================================== */
@ -205,21 +222,20 @@ static int pool_ptr = 0;
#define NEXT_BUFFER (buffer_pool[pool_ptr = ((pool_ptr + 1) % POOL_ENTRIES)])
/* ================================================== */
/* Convert a timeval into a temporary string, largely for diagnostic
display */
/* Convert a timespec into a temporary string, largely for diagnostic display */
char *
UTI_TimevalToString(struct timeval *tv)
UTI_TimespecToString(struct timespec *ts)
{
char *result;
result = NEXT_BUFFER;
#ifdef HAVE_LONG_TIME_T
snprintf(result, BUFFER_LENGTH, "%"PRId64".%06lu",
(int64_t)tv->tv_sec, (unsigned long)tv->tv_usec);
snprintf(result, BUFFER_LENGTH, "%"PRId64".%09lu",
(int64_t)ts->tv_sec, (unsigned long)ts->tv_nsec);
#else
snprintf(result, BUFFER_LENGTH, "%ld.%06lu",
(long)tv->tv_sec, (unsigned long)tv->tv_usec);
snprintf(result, BUFFER_LENGTH, "%ld.%09lu",
(long)ts->tv_sec, (unsigned long)ts->tv_nsec);
#endif
return result;
}
@ -229,11 +245,11 @@ UTI_TimevalToString(struct timeval *tv)
for diagnostic display */
char *
UTI_TimestampToString(NTP_int64 *ts)
UTI_TimestampToString(NTP_int64 *ntp_ts)
{
struct timeval tv;
UTI_Int64ToTimeval(ts, &tv);
return UTI_TimevalToString(&tv);
struct timespec ts;
UTI_Int64ToTimespec(ntp_ts, &ts);
return UTI_TimespecToString(&ts);
}
/* ================================================== */
@ -589,13 +605,13 @@ UTI_TimeToLogForm(time_t t)
/* ================================================== */
void
UTI_AdjustTimeval(struct timeval *old_tv, struct timeval *when, struct timeval *new_tv, double *delta_time, double dfreq, double doffset)
UTI_AdjustTimespec(struct timespec *old_ts, struct timespec *when, struct timespec *new_ts, double *delta_time, double dfreq, double doffset)
{
double elapsed;
UTI_DiffTimevalsToDouble(&elapsed, when, old_tv);
UTI_DiffTimespecsToDouble(&elapsed, when, old_ts);
*delta_time = elapsed * dfreq - doffset;
UTI_AddDoubleToTimeval(old_tv, *delta_time, new_tv);
UTI_AddDoubleToTimespec(old_ts, *delta_time, new_ts);
}
/* ================================================== */
@ -652,28 +668,26 @@ UTI_DoubleToInt32(double x)
/* ================================================== */
/* Seconds part of NTP timestamp correponding to the origin of the
struct timeval format. */
/* Seconds part of NTP timestamp correponding to the origin of the time_t format */
#define JAN_1970 0x83aa7e80UL
#define NSEC_PER_NTP64 4.294967296
void
UTI_TimevalToInt64(struct timeval *src,
NTP_int64 *dest, NTP_int64 *fuzz)
UTI_TimespecToInt64(struct timespec *src, NTP_int64 *dest, NTP_int64 *fuzz)
{
uint32_t hi, lo, sec, usec;
uint32_t hi, lo, sec, nsec;
sec = (uint32_t)src->tv_sec;
usec = (uint32_t)src->tv_usec;
nsec = (uint32_t)src->tv_nsec;
/* Recognize zero as a special case - it always signifies
an 'unknown' value */
if (!usec && !sec) {
if (!nsec && !sec) {
hi = lo = 0;
} else {
hi = htonl(sec + JAN_1970);
/* This formula gives an error of about 0.1us worst case */
lo = htonl(4295 * usec - (usec >> 5) - (usec >> 9));
lo = htonl(NSEC_PER_NTP64 * nsec);
/* Add the fuzz */
if (fuzz) {
@ -689,8 +703,7 @@ UTI_TimevalToInt64(struct timeval *src,
/* ================================================== */
void
UTI_Int64ToTimeval(NTP_int64 *src,
struct timeval *dest)
UTI_Int64ToTimespec(NTP_int64 *src, struct timespec *dest)
{
uint32_t ntp_sec, ntp_frac;
@ -706,11 +719,10 @@ UTI_Int64ToTimeval(NTP_int64 *src,
#else
dest->tv_sec = ntp_sec - JAN_1970;
#endif
/* Until I invent a slick way to do this, just do it the obvious way */
dest->tv_usec = (int)(0.5 + (double)(ntp_frac) / 4294.967296);
UTI_NormaliseTimeval(dest);
dest->tv_nsec = ntp_frac / NSEC_PER_NTP64 + 0.5;
UTI_NormaliseTimespec(dest);
}
/* ================================================== */
@ -722,7 +734,7 @@ UTI_Int64ToTimeval(NTP_int64 *src,
#define MIN_ENDOFTIME_DISTANCE (365 * 24 * 3600)
int
UTI_IsTimeOffsetSane(struct timeval *tv, double offset)
UTI_IsTimeOffsetSane(struct timespec *ts, double offset)
{
double t;
@ -730,7 +742,7 @@ UTI_IsTimeOffsetSane(struct timeval *tv, double offset)
if (!(offset > -MAX_OFFSET && offset < MAX_OFFSET))
return 0;
UTI_TimevalToDouble(tv, &t);
UTI_TimespecToDouble(ts, &t);
t += offset;
/* Time before 1970 is not considered valid */
@ -769,14 +781,14 @@ UTI_Log2ToDouble(int l)
/* ================================================== */
void
UTI_TimevalNetworkToHost(Timeval *src, struct timeval *dest)
UTI_TimespecNetworkToHost(Timespec *src, struct timespec *dest)
{
uint32_t sec_low;
#ifdef HAVE_LONG_TIME_T
uint32_t sec_high;
#endif
dest->tv_usec = ntohl(src->tv_nsec) / 1000;
dest->tv_nsec = ntohl(src->tv_nsec);
sec_low = ntohl(src->tv_sec_low);
#ifdef HAVE_LONG_TIME_T
sec_high = ntohl(src->tv_sec_high);
@ -788,15 +800,15 @@ UTI_TimevalNetworkToHost(Timeval *src, struct timeval *dest)
dest->tv_sec = sec_low;
#endif
UTI_NormaliseTimeval(dest);
UTI_NormaliseTimespec(dest);
}
/* ================================================== */
void
UTI_TimevalHostToNetwork(struct timeval *src, Timeval *dest)
UTI_TimespecHostToNetwork(struct timespec *src, Timespec *dest)
{
dest->tv_nsec = htonl(src->tv_usec * 1000);
dest->tv_nsec = htonl(src->tv_nsec);
#ifdef HAVE_LONG_TIME_T
dest->tv_sec_high = htonl((uint64_t)src->tv_sec >> 32);
#else

58
util.h
View file

@ -34,6 +34,26 @@
#include "candm.h"
#include "hash.h"
/* Zero a timespec */
extern void UTI_ZeroTimespec(struct timespec *ts);
/* Convert a timeval into a timespec */
extern void UTI_TimevalToTimespec(struct timeval *tv, struct timespec *ts);
/* Convert a timespec into a timeval */
extern void UTI_TimespecToTimeval(struct timespec *ts, struct timeval *tv);
/* Convert a timespec into a floating point number of seconds */
extern void UTI_TimespecToDouble(struct timespec *ts, double *d);
/* Convert a number of seconds expressed in floating point into a
timespec */
extern void UTI_DoubleToTimespec(double d, struct timespec *ts);
/* Normalise a timespec, by adding or subtracting seconds to bring
its nanosecond field into range */
extern void UTI_NormaliseTimespec(struct timespec *ts);
/* Convert a timeval into a floating point number of seconds */
extern void UTI_TimevalToDouble(struct timeval *a, double *b);
@ -41,34 +61,34 @@ extern void UTI_TimevalToDouble(struct timeval *a, double *b);
timeval */
extern void UTI_DoubleToTimeval(double a, struct timeval *b);
/* Returns -1 if a comes earlier than b, 0 if a is the same time as b,
and +1 if a comes after b */
extern int UTI_CompareTimevals(struct timeval *a, struct timeval *b);
/* Normalise a struct timeval, by adding or subtracting seconds to bring
its microseconds field into range */
extern void UTI_NormaliseTimeval(struct timeval *x);
/* Returns -1 if a comes earlier than b, 0 if a is the same time as b,
and +1 if a comes after b */
extern int UTI_CompareTimespecs(struct timespec *a, struct timespec *b);
/* Calculate result = a - b */
extern void UTI_DiffTimevals(struct timeval *result, struct timeval *a, struct timeval *b);
extern void UTI_DiffTimespecs(struct timespec *result, struct timespec *a, struct timespec *b);
/* Calculate result = a - b and return as a double */
extern void UTI_DiffTimevalsToDouble(double *result, struct timeval *a, struct timeval *b);
extern void UTI_DiffTimespecsToDouble(double *result, struct timespec *a, struct timespec *b);
/* Add a double increment to a timeval to get a new one. 'start' is
/* Add a double increment to a timespec to get a new one. 'start' is
the starting time, 'end' is the result that we return. This is
safe to use if start and end are the same */
extern void UTI_AddDoubleToTimeval(struct timeval *start, double increment, struct timeval *end);
extern void UTI_AddDoubleToTimespec(struct timespec *start, double increment, struct timespec *end);
/* Calculate the average and difference (as a double) of two timevals */
extern void UTI_AverageDiffTimevals(struct timeval *earlier, struct timeval *later, struct timeval *average, double *diff);
/* Calculate the average and difference (as a double) of two timespecs */
extern void UTI_AverageDiffTimespecs(struct timespec *earlier, struct timespec *later, struct timespec *average, double *diff);
/* Calculate result = a - b + c */
extern void UTI_AddDiffToTimeval(struct timeval *a, struct timeval *b, struct timeval *c, struct timeval *result);
extern void UTI_AddDiffToTimespec(struct timespec *a, struct timespec *b, struct timespec *c, struct timespec *result);
/* Convert a timeval into a temporary string, largely for diagnostic
/* Convert a timespec into a temporary string, largely for diagnostic
display */
extern char *UTI_TimevalToString(struct timeval *tv);
extern char *UTI_TimespecToString(struct timespec *ts);
/* Convert an NTP timestamp into a temporary string, largely for
diagnostic display */
@ -95,7 +115,7 @@ extern const char *UTI_SockaddrFamilyToString(int family);
extern char *UTI_TimeToLogForm(time_t t);
/* Adjust time following a frequency/offset change */
extern void UTI_AdjustTimeval(struct timeval *old_tv, struct timeval *when, struct timeval *new_tv, double *delta, double dfreq, double doffset);
extern void UTI_AdjustTimespec(struct timespec *old_ts, struct timespec *when, struct timespec *new_ts, double *delta_time, double dfreq, double doffset);
/* Get zero NTP timestamp with random bits below precision */
extern void UTI_GetInt64Fuzz(NTP_int64 *ts, int precision);
@ -103,18 +123,18 @@ extern void UTI_GetInt64Fuzz(NTP_int64 *ts, int precision);
extern double UTI_Int32ToDouble(NTP_int32 x);
extern NTP_int32 UTI_DoubleToInt32(double x);
extern void UTI_TimevalToInt64(struct timeval *src, NTP_int64 *dest, NTP_int64 *fuzz);
extern void UTI_TimespecToInt64(struct timespec *src, NTP_int64 *dest, NTP_int64 *fuzz);
extern void UTI_Int64ToTimeval(NTP_int64 *src, struct timeval *dest);
extern void UTI_Int64ToTimespec(NTP_int64 *src, struct timespec *dest);
/* Check if time + offset is sane */
extern int UTI_IsTimeOffsetSane(struct timeval *tv, double offset);
extern int UTI_IsTimeOffsetSane(struct timespec *ts, double offset);
/* Get 2 raised to power of a signed integer */
extern double UTI_Log2ToDouble(int l);
extern void UTI_TimevalNetworkToHost(Timeval *src, struct timeval *dest);
extern void UTI_TimevalHostToNetwork(struct timeval *src, Timeval *dest);
extern void UTI_TimespecNetworkToHost(Timespec *src, struct timespec *dest);
extern void UTI_TimespecHostToNetwork(struct timespec *src, Timespec *dest);
extern double UTI_FloatNetworkToHost(Float x);
extern Float UTI_FloatHostToNetwork(double x);