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:
parent
0899ab52dd
commit
d0dfa1de9e
46 changed files with 685 additions and 654 deletions
14
candm.h
14
candm.h
|
@ -96,12 +96,12 @@
|
||||||
#define REQ_LOCAL2 56
|
#define REQ_LOCAL2 56
|
||||||
#define N_REQUEST_TYPES 57
|
#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 {
|
typedef struct {
|
||||||
uint32_t tv_sec_high;
|
uint32_t tv_sec_high;
|
||||||
uint32_t tv_sec_low;
|
uint32_t tv_sec_low;
|
||||||
uint32_t tv_nsec;
|
uint32_t tv_nsec;
|
||||||
} Timeval;
|
} Timespec;
|
||||||
|
|
||||||
/* This is used in tv_sec_high for 32-bit timestamps */
|
/* This is used in tv_sec_high for 32-bit timestamps */
|
||||||
#define TV_NOHIGHSEC 0x7fffffff
|
#define TV_NOHIGHSEC 0x7fffffff
|
||||||
|
@ -200,12 +200,12 @@ typedef struct {
|
||||||
} REQ_Modify_Makestep;
|
} REQ_Modify_Makestep;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Timeval ts;
|
Timespec ts;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Logon;
|
} REQ_Logon;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Timeval ts;
|
Timespec ts;
|
||||||
int32_t EOR;
|
int32_t EOR;
|
||||||
} REQ_Settime;
|
} REQ_Settime;
|
||||||
|
|
||||||
|
@ -512,7 +512,7 @@ typedef struct {
|
||||||
IPAddr ip_addr;
|
IPAddr ip_addr;
|
||||||
uint16_t stratum;
|
uint16_t stratum;
|
||||||
uint16_t leap_status;
|
uint16_t leap_status;
|
||||||
Timeval ref_time;
|
Timespec ref_time;
|
||||||
Float current_correction;
|
Float current_correction;
|
||||||
Float last_offset;
|
Float last_offset;
|
||||||
Float rms_offset;
|
Float rms_offset;
|
||||||
|
@ -540,7 +540,7 @@ typedef struct {
|
||||||
} RPY_Sourcestats;
|
} RPY_Sourcestats;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Timeval ref_time;
|
Timespec ref_time;
|
||||||
uint16_t n_samples;
|
uint16_t n_samples;
|
||||||
uint16_t n_runs;
|
uint16_t n_runs;
|
||||||
uint32_t span_seconds;
|
uint32_t span_seconds;
|
||||||
|
@ -590,7 +590,7 @@ typedef struct {
|
||||||
#define MAX_MANUAL_LIST_SAMPLES 16
|
#define MAX_MANUAL_LIST_SAMPLES 16
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Timeval when;
|
Timespec when;
|
||||||
Float slewed_offset;
|
Float slewed_offset;
|
||||||
Float orig_offset;
|
Float orig_offset;
|
||||||
Float residual;
|
Float residual;
|
||||||
|
|
32
client.c
32
client.c
|
@ -1685,7 +1685,7 @@ print_report(const char *format, ...)
|
||||||
unsigned long long_uinteger;
|
unsigned long long_uinteger;
|
||||||
unsigned int uinteger;
|
unsigned int uinteger;
|
||||||
int integer;
|
int integer;
|
||||||
struct timeval *tv;
|
struct timespec *ts;
|
||||||
struct tm *tm;
|
struct tm *tm;
|
||||||
double dbl;
|
double dbl;
|
||||||
|
|
||||||
|
@ -1800,9 +1800,9 @@ print_report(const char *format, ...)
|
||||||
else
|
else
|
||||||
print_nanoseconds(dbl);
|
print_nanoseconds(dbl);
|
||||||
break;
|
break;
|
||||||
case 'T': /* timeval as date and time in UTC */
|
case 'T': /* timespec as date and time in UTC */
|
||||||
tv = va_arg(ap, struct timeval *);
|
ts = va_arg(ap, struct timespec *);
|
||||||
tm = gmtime(&tv->tv_sec);
|
tm = gmtime(&ts->tv_sec);
|
||||||
if (!tm)
|
if (!tm)
|
||||||
break;
|
break;
|
||||||
strftime(buf, sizeof (buf), "%a %b %d %T %Y", tm);
|
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);
|
long_uinteger = va_arg(ap, unsigned long);
|
||||||
printf("%*lu", width, long_uinteger);
|
printf("%*lu", width, long_uinteger);
|
||||||
break;
|
break;
|
||||||
case 'V': /* timeval as seconds since epoch */
|
case 'V': /* timespec as seconds since epoch */
|
||||||
tv = va_arg(ap, struct timeval *);
|
ts = va_arg(ap, struct timespec *);
|
||||||
printf("%s", UTI_TimevalToString(tv));
|
printf("%s", UTI_TimespecToString(ts));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Classic printf specifiers */
|
/* Classic printf specifiers */
|
||||||
|
@ -2081,7 +2081,7 @@ process_cmd_tracking(char *line)
|
||||||
IPAddr ip_addr;
|
IPAddr ip_addr;
|
||||||
uint32_t ref_id;
|
uint32_t ref_id;
|
||||||
char name[50];
|
char name[50];
|
||||||
struct timeval ref_time;
|
struct timespec ref_time;
|
||||||
const char *leap_status;
|
const char *leap_status;
|
||||||
|
|
||||||
request.command = htons(REQ_TRACKING);
|
request.command = htons(REQ_TRACKING);
|
||||||
|
@ -2112,7 +2112,7 @@ process_cmd_tracking(char *line)
|
||||||
break;
|
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"
|
print_report("Reference ID : %R (%s)\n"
|
||||||
"Stratum : %u\n"
|
"Stratum : %u\n"
|
||||||
|
@ -2230,13 +2230,13 @@ process_cmd_rtcreport(char *line)
|
||||||
{
|
{
|
||||||
CMD_Request request;
|
CMD_Request request;
|
||||||
CMD_Reply reply;
|
CMD_Reply reply;
|
||||||
struct timeval ref_time;
|
struct timespec ref_time;
|
||||||
|
|
||||||
request.command = htons(REQ_RTCREPORT);
|
request.command = htons(REQ_RTCREPORT);
|
||||||
if (!request_reply(&request, &reply, RPY_RTC, 0))
|
if (!request_reply(&request, &reply, RPY_RTC, 0))
|
||||||
return 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"
|
print_report("RTC ref time (UTC) : %T\n"
|
||||||
"Number of samples : %u\n"
|
"Number of samples : %u\n"
|
||||||
|
@ -2328,7 +2328,7 @@ process_cmd_manual_list(const char *line)
|
||||||
CMD_Reply reply;
|
CMD_Reply reply;
|
||||||
uint32_t i, n_samples;
|
uint32_t i, n_samples;
|
||||||
RPY_ManualListSample *sample;
|
RPY_ManualListSample *sample;
|
||||||
struct timeval when;
|
struct timespec when;
|
||||||
|
|
||||||
request.command = htons(REQ_MANUAL_LIST);
|
request.command = htons(REQ_MANUAL_LIST);
|
||||||
if (!request_reply(&request, &reply, RPY_MANUAL_LIST, 0))
|
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++) {
|
for (i = 0; i < n_samples; i++) {
|
||||||
sample = &reply.data.manual_list.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",
|
print_report("%2d %s %10.2f %10.2f %10.2f\n",
|
||||||
i, UTI_TimeToLogForm(when.tv_sec),
|
i, UTI_TimeToLogForm(when.tv_sec),
|
||||||
|
@ -2376,7 +2376,7 @@ process_cmd_manual_delete(CMD_Request *msg, const char *line)
|
||||||
static int
|
static int
|
||||||
process_cmd_settime(char *line)
|
process_cmd_settime(char *line)
|
||||||
{
|
{
|
||||||
struct timeval ts;
|
struct timespec ts;
|
||||||
time_t now, new_time;
|
time_t now, new_time;
|
||||||
CMD_Request request;
|
CMD_Request request;
|
||||||
CMD_Reply reply;
|
CMD_Reply reply;
|
||||||
|
@ -2391,8 +2391,8 @@ process_cmd_settime(char *line)
|
||||||
printf("510 - Could not parse date string\n");
|
printf("510 - Could not parse date string\n");
|
||||||
} else {
|
} else {
|
||||||
ts.tv_sec = new_time;
|
ts.tv_sec = new_time;
|
||||||
ts.tv_usec = 0;
|
ts.tv_nsec = 0;
|
||||||
UTI_TimevalHostToNetwork(&ts, &request.data.settime.ts);
|
UTI_TimespecHostToNetwork(&ts, &request.data.settime.ts);
|
||||||
request.command = htons(REQ_SETTIME);
|
request.command = htons(REQ_SETTIME);
|
||||||
if (request_reply(&request, &reply, RPY_MANUAL_TIMESTAMP, 1)) {
|
if (request_reply(&request, &reply, RPY_MANUAL_TIMESTAMP, 1)) {
|
||||||
offset_cs = ntohl(reply.data.manual_timestamp.centiseconds);
|
offset_cs = ntohl(reply.data.manual_timestamp.centiseconds);
|
||||||
|
|
19
clientlog.c
19
clientlog.c
|
@ -336,23 +336,24 @@ CLG_Finalise(void)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static uint32_t
|
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
|
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)
|
uint16_t *tokens, uint32_t max_tokens, int token_shift, int8_t *rate)
|
||||||
{
|
{
|
||||||
uint32_t interval, now_ts, prev_hit, new_tokens;
|
uint32_t interval, now_ts, prev_hit, new_tokens;
|
||||||
int interval2;
|
int interval2;
|
||||||
|
|
||||||
now_ts = get_ts_from_timeval(now);
|
now_ts = get_ts_from_timespec(now);
|
||||||
|
|
||||||
prev_hit = *last_hit;
|
prev_hit = *last_hit;
|
||||||
*last_hit = now_ts;
|
*last_hit = now_ts;
|
||||||
|
@ -405,7 +406,7 @@ get_index(Record *record)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
CLG_LogNTPAccess(IPAddr *client, struct timeval *now)
|
CLG_LogNTPAccess(IPAddr *client, struct timespec *now)
|
||||||
{
|
{
|
||||||
Record *record;
|
Record *record;
|
||||||
|
|
||||||
|
@ -435,7 +436,7 @@ CLG_LogNTPAccess(IPAddr *client, struct timeval *now)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
CLG_LogCommandAccess(IPAddr *client, struct timeval *now)
|
CLG_LogCommandAccess(IPAddr *client, struct timespec *now)
|
||||||
{
|
{
|
||||||
Record *record;
|
Record *record;
|
||||||
|
|
||||||
|
@ -586,7 +587,7 @@ static uint32_t get_last_ago(uint32_t x, uint32_t y)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
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;
|
Record *record;
|
||||||
uint32_t now_ts;
|
uint32_t now_ts;
|
||||||
|
@ -599,7 +600,7 @@ CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *repo
|
||||||
if (record->ip_addr.family == IPADDR_UNSPEC)
|
if (record->ip_addr.family == IPADDR_UNSPEC)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
now_ts = get_ts_from_timeval(now);
|
now_ts = get_ts_from_timespec(now);
|
||||||
|
|
||||||
report->ip_addr = record->ip_addr;
|
report->ip_addr = record->ip_addr;
|
||||||
report->ntp_hits = record->ntp_hits;
|
report->ntp_hits = record->ntp_hits;
|
||||||
|
|
|
@ -33,15 +33,15 @@
|
||||||
|
|
||||||
extern void CLG_Initialise(void);
|
extern void CLG_Initialise(void);
|
||||||
extern void CLG_Finalise(void);
|
extern void CLG_Finalise(void);
|
||||||
extern int CLG_LogNTPAccess(IPAddr *client, struct timeval *now);
|
extern int CLG_LogNTPAccess(IPAddr *client, struct timespec *now);
|
||||||
extern int CLG_LogCommandAccess(IPAddr *client, struct timeval *now);
|
extern int CLG_LogCommandAccess(IPAddr *client, struct timespec *now);
|
||||||
extern int CLG_LimitNTPResponseRate(int index);
|
extern int CLG_LimitNTPResponseRate(int index);
|
||||||
extern int CLG_LimitCommandResponseRate(int index);
|
extern int CLG_LimitCommandResponseRate(int index);
|
||||||
|
|
||||||
/* And some reporting functions, for use by chronyc. */
|
/* And some reporting functions, for use by chronyc. */
|
||||||
|
|
||||||
extern int CLG_GetNumberOfIndices(void);
|
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);
|
extern void CLG_GetServerStatsReport(RPT_ServerStatsReport *report);
|
||||||
|
|
||||||
#endif /* GOT_CLIENTLOG_H */
|
#endif /* GOT_CLIENTLOG_H */
|
||||||
|
|
22
cmdmon.c
22
cmdmon.c
|
@ -564,10 +564,10 @@ handle_modify_makestep(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||||
static void
|
static void
|
||||||
handle_settime(CMD_Request *rx_message, CMD_Reply *tx_message)
|
handle_settime(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||||
{
|
{
|
||||||
struct timeval ts;
|
struct timespec ts;
|
||||||
long offset_cs;
|
long offset_cs;
|
||||||
double dfreq_ppm, new_afreq_ppm;
|
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()) {
|
if (!MNL_IsEnabled()) {
|
||||||
tx_message->status = htons(STT_NOTENABLED);
|
tx_message->status = htons(STT_NOTENABLED);
|
||||||
} else if (MNL_AcceptTimestamp(&ts, &offset_cs, &dfreq_ppm, &new_afreq_ppm)) {
|
} 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)
|
handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||||
{
|
{
|
||||||
RPT_SourceReport report;
|
RPT_SourceReport report;
|
||||||
struct timeval now_corr;
|
struct timespec now_corr;
|
||||||
|
|
||||||
/* Get data */
|
/* Get data */
|
||||||
SCH_GetLastEventTime(&now_corr, NULL, NULL);
|
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);
|
UTI_IPHostToNetwork(&rpt.ip_addr, &tx_message->data.tracking.ip_addr);
|
||||||
tx_message->data.tracking.stratum = htons(rpt.stratum);
|
tx_message->data.tracking.stratum = htons(rpt.stratum);
|
||||||
tx_message->data.tracking.leap_status = htons(rpt.leap_status);
|
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.current_correction = UTI_FloatHostToNetwork(rpt.current_correction);
|
||||||
tx_message->data.tracking.last_offset = UTI_FloatHostToNetwork(rpt.last_offset);
|
tx_message->data.tracking.last_offset = UTI_FloatHostToNetwork(rpt.last_offset);
|
||||||
tx_message->data.tracking.rms_offset = UTI_FloatHostToNetwork(rpt.rms_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)
|
handle_smoothing(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||||
{
|
{
|
||||||
RPT_SmoothingReport report;
|
RPT_SmoothingReport report;
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
|
|
||||||
SCH_GetLastEventTime(&now, NULL, NULL);
|
SCH_GetLastEventTime(&now, NULL, NULL);
|
||||||
|
|
||||||
|
@ -940,7 +940,7 @@ handle_smoothing(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||||
static void
|
static void
|
||||||
handle_smoothtime(CMD_Request *rx_message, CMD_Reply *tx_message)
|
handle_smoothtime(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||||
{
|
{
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
int option;
|
int option;
|
||||||
|
|
||||||
if (!SMT_IsEnabled()) {
|
if (!SMT_IsEnabled()) {
|
||||||
|
@ -971,7 +971,7 @@ handle_sourcestats(CMD_Request *rx_message, CMD_Reply *tx_message)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
RPT_SourcestatsReport report;
|
RPT_SourcestatsReport report;
|
||||||
struct timeval now_corr;
|
struct timespec now_corr;
|
||||||
|
|
||||||
SCH_GetLastEventTime(&now_corr, NULL, NULL);
|
SCH_GetLastEventTime(&now_corr, NULL, NULL);
|
||||||
status = SRC_ReportSourcestats(ntohl(rx_message->data.sourcestats.index),
|
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);
|
status = RTC_GetReport(&report);
|
||||||
if (status) {
|
if (status) {
|
||||||
tx_message->reply = htons(RPY_RTC);
|
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_samples = htons(report.n_samples);
|
||||||
tx_message->data.rtc.n_runs = htons(report.n_runs);
|
tx_message->data.rtc.n_runs = htons(report.n_runs);
|
||||||
tx_message->data.rtc.span_seconds = htonl(report.span_seconds);
|
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;
|
RPY_ClientAccesses_Client *client;
|
||||||
int n_indices;
|
int n_indices;
|
||||||
uint32_t i, j, req_first_index, req_n_clients;
|
uint32_t i, j, req_first_index, req_n_clients;
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
|
|
||||||
SCH_GetLastEventTime(&now, NULL, NULL);
|
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);
|
tx_message->data.manual_list.n_samples = htonl(n_samples);
|
||||||
for (i=0; i<n_samples; i++) {
|
for (i=0; i<n_samples; i++) {
|
||||||
sample = &tx_message->data.manual_list.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->slewed_offset = UTI_FloatHostToNetwork(report[i].slewed_offset);
|
||||||
sample->orig_offset = UTI_FloatHostToNetwork(report[i].orig_offset);
|
sample->orig_offset = UTI_FloatHostToNetwork(report[i].orig_offset);
|
||||||
sample->residual = UTI_FloatHostToNetwork(report[i].residual);
|
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;
|
socklen_t from_length;
|
||||||
IPAddr remote_ip;
|
IPAddr remote_ip;
|
||||||
unsigned short remote_port, rx_command;
|
unsigned short remote_port, rx_command;
|
||||||
struct timeval now, cooked_now;
|
struct timespec now, cooked_now;
|
||||||
|
|
||||||
rx_message_length = sizeof(rx_message);
|
rx_message_length = sizeof(rx_message);
|
||||||
from_length = sizeof(where_from);
|
from_length = sizeof(where_from);
|
||||||
|
|
19
keys.c
19
keys.c
|
@ -103,9 +103,9 @@ static int
|
||||||
determine_hash_delay(uint32_t key_id)
|
determine_hash_delay(uint32_t key_id)
|
||||||
{
|
{
|
||||||
NTP_Packet pkt;
|
NTP_Packet pkt;
|
||||||
struct timeval before, after;
|
struct timespec before, after;
|
||||||
unsigned long usecs, min_usecs=0;
|
double diff, min_diff;
|
||||||
int i;
|
int i, nsecs;
|
||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
LCL_ReadRawTime(&before);
|
LCL_ReadRawTime(&before);
|
||||||
|
@ -113,19 +113,18 @@ determine_hash_delay(uint32_t key_id)
|
||||||
(unsigned char *)&pkt.auth_data, sizeof (pkt.auth_data));
|
(unsigned char *)&pkt.auth_data, sizeof (pkt.auth_data));
|
||||||
LCL_ReadRawTime(&after);
|
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) {
|
if (i == 0 || min_diff > diff)
|
||||||
min_usecs = usecs;
|
min_diff = diff;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add on a bit extra to allow for copying, conversions etc */
|
/* 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
75
local.c
|
@ -106,37 +106,42 @@ static double max_clock_error;
|
||||||
under 1s of busy waiting. */
|
under 1s of busy waiting. */
|
||||||
#define NITERS 100
|
#define NITERS 100
|
||||||
|
|
||||||
|
#define NSEC_PER_SEC 1000000000
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calculate_sys_precision(void)
|
calculate_sys_precision(void)
|
||||||
{
|
{
|
||||||
struct timeval tv, old_tv;
|
struct timespec ts, old_ts;
|
||||||
int dusec, best_dusec;
|
int iters, diff, best;
|
||||||
int iters;
|
|
||||||
|
|
||||||
gettimeofday(&old_tv, NULL);
|
LCL_ReadRawTime(&old_ts);
|
||||||
best_dusec = 1000000; /* Assume we must be better than a second */
|
|
||||||
|
/* Assume we must be better than a second */
|
||||||
|
best = NSEC_PER_SEC;
|
||||||
iters = 0;
|
iters = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
gettimeofday(&tv, NULL);
|
LCL_ReadRawTime(&ts);
|
||||||
dusec = 1000000*(tv.tv_sec - old_tv.tv_sec) + (tv.tv_usec - old_tv.tv_usec);
|
|
||||||
old_tv = tv;
|
diff = NSEC_PER_SEC * (ts.tv_sec - old_ts.tv_sec) + (ts.tv_nsec - old_ts.tv_nsec);
|
||||||
if (dusec > 0) {
|
|
||||||
if (dusec < best_dusec) {
|
old_ts = ts;
|
||||||
best_dusec = dusec;
|
if (diff > 0) {
|
||||||
}
|
if (diff < best)
|
||||||
|
best = diff;
|
||||||
iters++;
|
iters++;
|
||||||
}
|
}
|
||||||
} while (iters < NITERS);
|
} 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 */
|
/* Get rounded log2 value of the measured precision */
|
||||||
precision_log = 0;
|
precision_log = 0;
|
||||||
while (best_dusec < 707107) {
|
while (best < 707106781) {
|
||||||
precision_log--;
|
precision_log--;
|
||||||
best_dusec *= 2;
|
best *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_LOG(LOGF_Local, "Clock precision %.9f (%d)", precision_quantum, precision_log);
|
DEBUG_LOG(LOGF_Local, "Clock precision %.9f (%d)", precision_quantum, precision_log);
|
||||||
|
@ -278,7 +283,7 @@ LCL_IsFirstParameterChangeHandler(LCL_ParameterChangeHandler handler)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
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,
|
double dfreq, double doffset,
|
||||||
LCL_ChangeType change_type)
|
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 */
|
I can't think of a Unix system where it would not be */
|
||||||
|
|
||||||
void
|
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");
|
LOG_FATAL(LOGF_Local, "gettimeofday() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UTI_TimevalToTimespec(&tv, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
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_ReadRawTime(&raw);
|
||||||
LCL_CookTime(&raw, result, err);
|
LCL_CookTime(&raw, result, err);
|
||||||
|
@ -370,18 +379,18 @@ LCL_ReadCookedTime(struct timeval *result, double *err)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
LCL_CookTime(struct timeval *raw, struct timeval *cooked, double *err)
|
LCL_CookTime(struct timespec *raw, struct timespec *cooked, double *err)
|
||||||
{
|
{
|
||||||
double correction;
|
double correction;
|
||||||
|
|
||||||
LCL_GetOffsetCorrection(raw, &correction, err);
|
LCL_GetOffsetCorrection(raw, &correction, err);
|
||||||
UTI_AddDoubleToTimeval(raw, correction, cooked);
|
UTI_AddDoubleToTimespec(raw, correction, cooked);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
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 */
|
/* Call system specific driver to get correction */
|
||||||
(*drv_offset_convert)(raw, correction, err);
|
(*drv_offset_convert)(raw, correction, err);
|
||||||
|
@ -421,7 +430,7 @@ clamp_freq(double freq)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static int
|
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 */
|
/* Check if the time will be still sane with accumulated offset */
|
||||||
if (UTI_IsTimeOffsetSane(now, -offset))
|
if (UTI_IsTimeOffsetSane(now, -offset))
|
||||||
|
@ -439,7 +448,7 @@ check_offset(struct timeval *now, double offset)
|
||||||
void
|
void
|
||||||
LCL_SetAbsoluteFrequency(double afreq_ppm)
|
LCL_SetAbsoluteFrequency(double afreq_ppm)
|
||||||
{
|
{
|
||||||
struct timeval raw, cooked;
|
struct timespec raw, cooked;
|
||||||
double dfreq;
|
double dfreq;
|
||||||
|
|
||||||
afreq_ppm = clamp_freq(afreq_ppm);
|
afreq_ppm = clamp_freq(afreq_ppm);
|
||||||
|
@ -470,7 +479,7 @@ LCL_SetAbsoluteFrequency(double afreq_ppm)
|
||||||
void
|
void
|
||||||
LCL_AccumulateDeltaFrequency(double dfreq)
|
LCL_AccumulateDeltaFrequency(double dfreq)
|
||||||
{
|
{
|
||||||
struct timeval raw, cooked;
|
struct timespec raw, cooked;
|
||||||
double old_freq_ppm;
|
double old_freq_ppm;
|
||||||
|
|
||||||
old_freq_ppm = current_freq_ppm;
|
old_freq_ppm = current_freq_ppm;
|
||||||
|
@ -499,7 +508,7 @@ LCL_AccumulateDeltaFrequency(double dfreq)
|
||||||
void
|
void
|
||||||
LCL_AccumulateOffset(double offset, double corr_rate)
|
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
|
/* In this case, the cooked time to be passed to the notify clients
|
||||||
has to be the cooked time BEFORE the change was made */
|
has to be the cooked time BEFORE the change was made */
|
||||||
|
@ -521,7 +530,7 @@ LCL_AccumulateOffset(double offset, double corr_rate)
|
||||||
int
|
int
|
||||||
LCL_ApplyStepOffset(double offset)
|
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
|
/* In this case, the cooked time to be passed to the notify clients
|
||||||
has to be the cooked time BEFORE the change was made */
|
has to be the cooked time BEFORE the change was made */
|
||||||
|
@ -549,7 +558,7 @@ LCL_ApplyStepOffset(double offset)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
LCL_NotifyExternalTimeStep(struct timeval *raw, struct timeval *cooked,
|
LCL_NotifyExternalTimeStep(struct timespec *raw, struct timespec *cooked,
|
||||||
double offset, double dispersion)
|
double offset, double dispersion)
|
||||||
{
|
{
|
||||||
/* Dispatch to all handlers */
|
/* Dispatch to all handlers */
|
||||||
|
@ -563,7 +572,7 @@ LCL_NotifyExternalTimeStep(struct timeval *raw, struct timeval *cooked,
|
||||||
void
|
void
|
||||||
LCL_NotifyLeap(int leap)
|
LCL_NotifyLeap(int leap)
|
||||||
{
|
{
|
||||||
struct timeval raw, cooked;
|
struct timespec raw, cooked;
|
||||||
|
|
||||||
LCL_ReadRawTime(&raw);
|
LCL_ReadRawTime(&raw);
|
||||||
LCL_CookTime(&raw, &cooked, NULL);
|
LCL_CookTime(&raw, &cooked, NULL);
|
||||||
|
@ -580,7 +589,7 @@ LCL_NotifyLeap(int leap)
|
||||||
void
|
void
|
||||||
LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset, double corr_rate)
|
LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset, double corr_rate)
|
||||||
{
|
{
|
||||||
struct timeval raw, cooked;
|
struct timespec raw, cooked;
|
||||||
double old_freq_ppm;
|
double old_freq_ppm;
|
||||||
|
|
||||||
LCL_ReadRawTime(&raw);
|
LCL_ReadRawTime(&raw);
|
||||||
|
@ -657,7 +666,7 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq,
|
||||||
int
|
int
|
||||||
LCL_MakeStep(void)
|
LCL_MakeStep(void)
|
||||||
{
|
{
|
||||||
struct timeval raw;
|
struct timespec raw;
|
||||||
double correction;
|
double correction;
|
||||||
|
|
||||||
LCL_ReadRawTime(&raw);
|
LCL_ReadRawTime(&raw);
|
||||||
|
|
12
local.h
12
local.h
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
/* Read the system clock. This is analogous to gettimeofday(),
|
/* Read the system clock. This is analogous to gettimeofday(),
|
||||||
but with the timezone information ignored */
|
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
|
/* Read the system clock, corrected according to all accumulated
|
||||||
drifts and uncompensated offsets.
|
drifts and uncompensated offsets.
|
||||||
|
@ -44,15 +44,15 @@ extern void LCL_ReadRawTime(struct timeval *);
|
||||||
adjtime()-like interface to correct offsets, and to adjust the
|
adjtime()-like interface to correct offsets, and to adjust the
|
||||||
frequency), we must correct the raw time to get this value */
|
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. */
|
/* 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
|
/* Read the current offset between the system clock and true time
|
||||||
(i.e. 'cooked' - 'raw') (in seconds). */
|
(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
|
/* Type of routines that may be invoked as callbacks when there is a
|
||||||
change to the frequency or offset.
|
change to the frequency or offset.
|
||||||
|
@ -79,7 +79,7 @@ typedef enum {
|
||||||
} LCL_ChangeType;
|
} LCL_ChangeType;
|
||||||
|
|
||||||
typedef void (*LCL_ParameterChangeHandler)
|
typedef void (*LCL_ParameterChangeHandler)
|
||||||
(struct timeval *raw, struct timeval *cooked,
|
(struct timespec *raw, struct timespec *cooked,
|
||||||
double dfreq,
|
double dfreq,
|
||||||
double doffset,
|
double doffset,
|
||||||
LCL_ChangeType change_type,
|
LCL_ChangeType change_type,
|
||||||
|
@ -163,7 +163,7 @@ extern int LCL_ApplyStepOffset(double offset);
|
||||||
|
|
||||||
/* Routine to invoke notify handlers on an unexpected time jump
|
/* Routine to invoke notify handlers on an unexpected time jump
|
||||||
in system clock */
|
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);
|
double offset, double dispersion);
|
||||||
|
|
||||||
/* Routine to invoke notify handlers on leap second when the system clock
|
/* Routine to invoke notify handlers on leap second when the system clock
|
||||||
|
|
2
localp.h
2
localp.h
|
@ -52,7 +52,7 @@ typedef int (*lcl_ApplyStepOffsetDriver)(double offset);
|
||||||
/* System driver to convert a raw time to an adjusted (cooked) time.
|
/* 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
|
The number of seconds returned in 'corr' have to be added to the
|
||||||
raw time to get the corrected time */
|
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 */
|
/* System driver to schedule leap second */
|
||||||
typedef void (*lcl_SetLeapDriver)(int leap);
|
typedef void (*lcl_SetLeapDriver)(int leap);
|
||||||
|
|
26
manual.c
26
manual.c
|
@ -47,7 +47,7 @@ static int enabled = 0;
|
||||||
|
|
||||||
/* More recent samples at highest indices */
|
/* More recent samples at highest indices */
|
||||||
typedef struct {
|
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 orig_offset; /*+ Not modified by slew samples */
|
||||||
double offset; /*+ if we are fast of the supplied reference */
|
double offset; /*+ if we are fast of the supplied reference */
|
||||||
double residual; /*+ regression residual (sign convention given by
|
double residual; /*+ regression residual (sign convention given by
|
||||||
|
@ -64,8 +64,8 @@ static int n_samples;
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
slew_samples(struct timeval *raw,
|
slew_samples(struct timespec *raw,
|
||||||
struct timeval *cooked,
|
struct timespec *cooked,
|
||||||
double dfreq,
|
double dfreq,
|
||||||
double doffset,
|
double doffset,
|
||||||
LCL_ChangeType change_type,
|
LCL_ChangeType change_type,
|
||||||
|
@ -97,7 +97,7 @@ MNL_Finalise(void)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static 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 agos[MAX_SAMPLES], offsets[MAX_SAMPLES];
|
||||||
double b0, b1;
|
double b0, b1;
|
||||||
|
@ -110,7 +110,7 @@ estimate_and_set_system(struct timeval *now, int offset_provided, double offset,
|
||||||
|
|
||||||
if (n_samples > 1) {
|
if (n_samples > 1) {
|
||||||
for (i=0; i<n_samples; i++) {
|
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;
|
offsets[i] = samples[i].offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,9 +173,9 @@ estimate_and_set_system(struct timeval *now, int offset_provided, double offset,
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
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;
|
double offset, diff;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -189,12 +189,12 @@ MNL_AcceptTimestamp(struct timeval *ts, long *offset_cs, double *dfreq_ppm, doub
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (n_samples) {
|
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)
|
if (diff < MIN_SAMPLE_SEPARATION)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UTI_DiffTimevalsToDouble(&offset, &now, ts);
|
UTI_DiffTimespecsToDouble(&offset, &now, ts);
|
||||||
|
|
||||||
/* Check if buffer full up */
|
/* Check if buffer full up */
|
||||||
if (n_samples == MAX_SAMPLES) {
|
if (n_samples == MAX_SAMPLES) {
|
||||||
|
@ -224,8 +224,8 @@ MNL_AcceptTimestamp(struct timeval *ts, long *offset_cs, double *dfreq_ppm, doub
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
slew_samples(struct timeval *raw,
|
slew_samples(struct timespec *raw,
|
||||||
struct timeval *cooked,
|
struct timespec *cooked,
|
||||||
double dfreq,
|
double dfreq,
|
||||||
double doffset,
|
double doffset,
|
||||||
LCL_ChangeType change_type,
|
LCL_ChangeType change_type,
|
||||||
|
@ -239,7 +239,7 @@ slew_samples(struct timeval *raw,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<n_samples; i++) {
|
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);
|
dfreq, doffset);
|
||||||
samples[i].offset += delta_time;
|
samples[i].offset += delta_time;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ int
|
||||||
MNL_DeleteSample(int index)
|
MNL_DeleteSample(int index)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
|
|
||||||
if ((index < 0) || (index >= n_samples)) {
|
if ((index < 0) || (index >= n_samples)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
2
manual.h
2
manual.h
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
extern void MNL_Initialise(void);
|
extern void MNL_Initialise(void);
|
||||||
extern void MNL_Finalise(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_Enable(void);
|
||||||
extern void MNL_Disable(void);
|
extern void MNL_Disable(void);
|
||||||
|
|
107
ntp_core.c
107
ntp_core.c
|
@ -154,18 +154,18 @@ struct NCR_Instance_Record {
|
||||||
parameters for the current reference. (It must be stored
|
parameters for the current reference. (It must be stored
|
||||||
relative to local time to permit frequency and offset adjustments
|
relative to local time to permit frequency and offset adjustments
|
||||||
to be made when we trim the local clock). */
|
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.
|
/* Local timestamp when we last transmitted a packet to the source.
|
||||||
We store two versions. The first is in NTP format, and is used
|
We store two versions. The first is in NTP format, and is used
|
||||||
to validate the next received packet from the source.
|
to validate the next received packet from the source.
|
||||||
Additionally, this is corrected to bring it into line with the
|
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
|
relative to the local clock. We modify this in accordance with
|
||||||
local clock frequency/offset changes, and use this for computing
|
local clock frequency/offset changes, and use this for computing
|
||||||
statistics about the source when a return packet arrives. */
|
statistics about the source when a return packet arrives. */
|
||||||
NTP_int64 local_ntp_tx;
|
NTP_int64 local_ntp_tx;
|
||||||
struct timeval local_tx;
|
struct timespec local_tx;
|
||||||
|
|
||||||
/* The instance record in the main source management module. This
|
/* The instance record in the main source management module. This
|
||||||
performs the statistical analysis on the samples we generate */
|
performs the statistical analysis on the samples we generate */
|
||||||
|
@ -285,30 +285,30 @@ do_size_checks(void)
|
||||||
static void
|
static void
|
||||||
do_time_checks(void)
|
do_time_checks(void)
|
||||||
{
|
{
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
time_t warning_advance = 3600 * 24 * 365 * 10; /* 10 years */
|
time_t warning_advance = 3600 * 24 * 365 * 10; /* 10 years */
|
||||||
|
|
||||||
#ifdef HAVE_LONG_TIME_T
|
#ifdef HAVE_LONG_TIME_T
|
||||||
/* Check that time before NTP_ERA_SPLIT underflows correctly */
|
/* Check that time before NTP_ERA_SPLIT underflows correctly */
|
||||||
|
|
||||||
struct timeval tv1 = {NTP_ERA_SPLIT, 1}, tv2 = {NTP_ERA_SPLIT - 1, 1};
|
struct timespec ts1 = {NTP_ERA_SPLIT, 1}, ts2 = {NTP_ERA_SPLIT - 1, 1};
|
||||||
NTP_int64 ntv1, ntv2;
|
NTP_int64 nts1, nts2;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
UTI_TimevalToInt64(&tv1, &ntv1, NULL);
|
UTI_TimespecToInt64(&ts1, &nts1, NULL);
|
||||||
UTI_TimevalToInt64(&tv2, &ntv2, NULL);
|
UTI_TimespecToInt64(&ts2, &nts2, NULL);
|
||||||
UTI_Int64ToTimeval(&ntv1, &tv1);
|
UTI_Int64ToTimespec(&nts1, &ts1);
|
||||||
UTI_Int64ToTimeval(&ntv2, &tv2);
|
UTI_Int64ToTimespec(&nts2, &ts2);
|
||||||
|
|
||||||
r = tv1.tv_sec == NTP_ERA_SPLIT &&
|
r = ts1.tv_sec == NTP_ERA_SPLIT &&
|
||||||
tv1.tv_sec + (1ULL << 32) - 1 == tv2.tv_sec;
|
ts1.tv_sec + (1ULL << 32) - 1 == ts2.tv_sec;
|
||||||
|
|
||||||
assert(r);
|
assert(r);
|
||||||
|
|
||||||
LCL_ReadRawTime(&now);
|
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!",
|
LOG(LOGS_WARN, LOGF_NtpCore, "Assumed NTP time ends at %s!",
|
||||||
UTI_TimeToLogForm(tv2.tv_sec));
|
UTI_TimeToLogForm(ts2.tv_sec));
|
||||||
#else
|
#else
|
||||||
LCL_ReadRawTime(&now);
|
LCL_ReadRawTime(&now);
|
||||||
if (now.tv_sec > 0x7fffffff - warning_advance)
|
if (now.tv_sec > 0x7fffffff - warning_advance)
|
||||||
|
@ -385,7 +385,7 @@ static void
|
||||||
start_initial_timeout(NCR_Instance inst)
|
start_initial_timeout(NCR_Instance inst)
|
||||||
{
|
{
|
||||||
double delay, last_tx;
|
double delay, last_tx;
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
|
|
||||||
if (!inst->tx_timeout_id) {
|
if (!inst->tx_timeout_id) {
|
||||||
/* This will be the first transmission after mode change */
|
/* 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
|
the interval between packets at least as long as the current polling
|
||||||
interval */
|
interval */
|
||||||
SCH_GetLastEventTime(&now, NULL, NULL);
|
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)
|
if (last_tx < 0.0)
|
||||||
last_tx = 0.0;
|
last_tx = 0.0;
|
||||||
delay = get_transmit_delay(inst, 0, 0.0) - last_tx;
|
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->tx_suspended = 1;
|
||||||
result->opmode = params->online ? MD_ONLINE : MD_OFFLINE;
|
result->opmode = params->online ? MD_ONLINE : MD_OFFLINE;
|
||||||
result->local_poll = result->minpoll;
|
result->local_poll = result->minpoll;
|
||||||
result->local_tx.tv_sec = 0;
|
UTI_ZeroTimespec(&result->local_tx);
|
||||||
result->local_tx.tv_usec = 0;
|
|
||||||
|
|
||||||
NCR_ResetInstance(result);
|
NCR_ResetInstance(result);
|
||||||
|
|
||||||
|
@ -585,10 +584,9 @@ NCR_ResetInstance(NCR_Instance instance)
|
||||||
|
|
||||||
instance->remote_orig.hi = 0;
|
instance->remote_orig.hi = 0;
|
||||||
instance->remote_orig.lo = 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.hi = 0;
|
||||||
instance->local_ntp_tx.lo = 0;
|
instance->local_ntp_tx.lo = 0;
|
||||||
|
UTI_ZeroTimespec(&instance->local_rx);
|
||||||
|
|
||||||
if (instance->local_poll != instance->minpoll) {
|
if (instance->local_poll != instance->minpoll) {
|
||||||
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 */
|
int auth_mode, /* The authentication mode */
|
||||||
uint32_t key_id, /* The authentication key ID */
|
uint32_t key_id, /* The authentication key ID */
|
||||||
NTP_int64 *orig_ts, /* Originate timestamp (from received packet) */
|
NTP_int64 *orig_ts, /* Originate timestamp (from received packet) */
|
||||||
struct timeval *local_rx, /* Local time request packet was received */
|
struct timespec *local_rx, /* Local time request packet was received */
|
||||||
struct timeval *local_tx, /* RESULT : Time this reply
|
struct timespec *local_tx, /* RESULT : Time this reply
|
||||||
is sent as local time, or
|
is sent as local time, or
|
||||||
NULL if don't want to
|
NULL if don't want to
|
||||||
know */
|
know */
|
||||||
|
@ -812,14 +810,14 @@ transmit_packet(NTP_Mode my_mode, /* The mode this machine wants to be */
|
||||||
{
|
{
|
||||||
NTP_Packet message;
|
NTP_Packet message;
|
||||||
int auth_len, length, ret, precision;
|
int auth_len, length, ret, precision;
|
||||||
struct timeval local_receive, local_transmit;
|
struct timespec local_receive, local_transmit;
|
||||||
NTP_int64 ts_fuzz;
|
NTP_int64 ts_fuzz;
|
||||||
|
|
||||||
/* Parameters read from reference module */
|
/* Parameters read from reference module */
|
||||||
int are_we_synchronised, our_stratum, smooth_time;
|
int are_we_synchronised, our_stratum, smooth_time;
|
||||||
NTP_Leap leap_status;
|
NTP_Leap leap_status;
|
||||||
uint32_t our_ref_id;
|
uint32_t our_ref_id;
|
||||||
struct timeval our_ref_time;
|
struct timespec our_ref_time;
|
||||||
double our_root_delay, our_root_dispersion, smooth_offset;
|
double our_root_delay, our_root_dispersion, smooth_offset;
|
||||||
|
|
||||||
/* Don't reply with version higher than ours */
|
/* 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 */
|
/* Don't reveal local time or state of the clock in client packets */
|
||||||
precision = 32;
|
precision = 32;
|
||||||
leap_status = our_stratum = our_ref_id = 0;
|
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;
|
our_root_delay = our_root_dispersion = 0.0;
|
||||||
|
UTI_ZeroTimespec(&our_ref_time);
|
||||||
} else {
|
} else {
|
||||||
/* This is accurate enough and cheaper than calling LCL_ReadCookedTime.
|
/* This is accurate enough and cheaper than calling LCL_ReadCookedTime.
|
||||||
A more accurate timestamp will be taken later in this function. */
|
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) {
|
if (smooth_time) {
|
||||||
our_ref_id = NTP_REFID_SMOOTH;
|
our_ref_id = NTP_REFID_SMOOTH;
|
||||||
UTI_AddDoubleToTimeval(&our_ref_time, smooth_offset, &our_ref_time);
|
UTI_AddDoubleToTimespec(&our_ref_time, smooth_offset, &our_ref_time);
|
||||||
UTI_AddDoubleToTimeval(local_rx, smooth_offset, &local_receive);
|
UTI_AddDoubleToTimespec(local_rx, smooth_offset, &local_receive);
|
||||||
} else {
|
} else {
|
||||||
local_receive = *local_rx;
|
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 */
|
/* 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 */
|
/* Originate - this comes from the last packet the source sent us */
|
||||||
message.originate_ts = *orig_ts;
|
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
|
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
|
the source like we have been running on our latest estimate of
|
||||||
frequency all along */
|
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. */
|
/* Prepare random bits which will be added to the transmit timestamp. */
|
||||||
UTI_GetInt64Fuzz(&ts_fuzz, precision);
|
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);
|
LCL_ReadCookedTime(&local_transmit, NULL);
|
||||||
|
|
||||||
if (smooth_time)
|
if (smooth_time)
|
||||||
UTI_AddDoubleToTimeval(&local_transmit, smooth_offset, &local_transmit);
|
UTI_AddDoubleToTimespec(&local_transmit, smooth_offset, &local_transmit);
|
||||||
|
|
||||||
length = NTP_NORMAL_PACKET_LENGTH;
|
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) {
|
if (auth_mode == AUTH_SYMMETRIC || auth_mode == AUTH_MSSNTP) {
|
||||||
/* Pre-compensate the transmit time by approx. how long it will
|
/* Pre-compensate the transmit time by approx. how long it will
|
||||||
take to generate the authentication data. */
|
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);
|
KEY_GetAuthDelay(key_id) : NSD_GetAuthDelay(key_id);
|
||||||
UTI_NormaliseTimeval(&local_transmit);
|
UTI_NormaliseTimespec(&local_transmit);
|
||||||
UTI_TimevalToInt64(&local_transmit, &message.transmit_ts, &ts_fuzz);
|
UTI_TimespecToInt64(&local_transmit, &message.transmit_ts, &ts_fuzz);
|
||||||
|
|
||||||
if (auth_mode == AUTH_SYMMETRIC) {
|
if (auth_mode == AUTH_SYMMETRIC) {
|
||||||
auth_len = KEY_GenerateAuth(key_id, (unsigned char *) &message,
|
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);
|
return NSD_SignAndSendPacket(key_id, &message, where_to, from, length);
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
ret = NIO_SendPacket(&message, where_to, from, length);
|
||||||
|
@ -1191,7 +1189,7 @@ check_packet_auth(NTP_Packet *pkt, int length,
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static int
|
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;
|
int pkt_leap;
|
||||||
uint32_t pkt_refid, pkt_key_id;
|
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
|
the same as either the transmit or receive time. The difference comes
|
||||||
in symmetric active mode, when the receive may come minutes after the
|
in symmetric active mode, when the receive may come minutes after the
|
||||||
transmit, and this time will be midway between the two */
|
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
|
/* 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
|
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 */
|
/* The skew and estimated frequency offset relative to the remote source */
|
||||||
double skew, source_freq_lo, source_freq_hi;
|
double skew, source_freq_lo, source_freq_hi;
|
||||||
|
|
||||||
/* These are the timeval equivalents of the remote epochs */
|
/* These are the timespec equivalents of the remote epochs */
|
||||||
struct timeval remote_receive_tv, remote_transmit_tv;
|
struct timespec remote_receive, remote_transmit;
|
||||||
struct timeval local_average, remote_average;
|
struct timespec local_average, remote_average;
|
||||||
double local_interval, remote_interval;
|
double local_interval, remote_interval;
|
||||||
|
|
||||||
/* RFC 5905 packet tests */
|
/* 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_delay = UTI_Int32ToDouble(message->root_delay);
|
||||||
pkt_root_dispersion = UTI_Int32ToDouble(message->root_dispersion);
|
pkt_root_dispersion = UTI_Int32ToDouble(message->root_dispersion);
|
||||||
|
|
||||||
UTI_Int64ToTimeval(&message->receive_ts, &remote_receive_tv);
|
UTI_Int64ToTimespec(&message->receive_ts, &remote_receive);
|
||||||
UTI_Int64ToTimeval(&message->transmit_ts, &remote_transmit_tv);
|
UTI_Int64ToTimespec(&message->transmit_ts, &remote_transmit);
|
||||||
|
|
||||||
/* Check if the packet is valid per RFC 5905, section 8.
|
/* Check if the packet is valid per RFC 5905, section 8.
|
||||||
The test values are 1 when passed and 0 when failed. */
|
The test values are 1 when passed and 0 when failed. */
|
||||||
|
@ -1330,10 +1328,10 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
|
||||||
|
|
||||||
SRC_GetFrequencyRange(inst->source, &source_freq_lo, &source_freq_hi);
|
SRC_GetFrequencyRange(inst->source, &source_freq_lo, &source_freq_hi);
|
||||||
|
|
||||||
UTI_AverageDiffTimevals(&remote_receive_tv, &remote_transmit_tv,
|
UTI_AverageDiffTimespecs(&remote_receive, &remote_transmit,
|
||||||
&remote_average, &remote_interval);
|
&remote_average, &remote_interval);
|
||||||
|
|
||||||
UTI_AverageDiffTimevals(&inst->local_tx, now,
|
UTI_AverageDiffTimespecs(&inst->local_tx, now,
|
||||||
&local_average, &local_interval);
|
&local_average, &local_interval);
|
||||||
|
|
||||||
/* In our case, we work out 'delay' as the worst case delay,
|
/* In our case, we work out 'delay' as the worst case delay,
|
||||||
|
@ -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
|
/* Calculate offset. Following the NTP definition, this is negative
|
||||||
if we are fast of the remote source. */
|
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 */
|
/* Apply configured correction */
|
||||||
offset += inst->offset_correction;
|
offset += inst->offset_correction;
|
||||||
|
@ -1549,7 +1547,7 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
|
||||||
int
|
int
|
||||||
NCR_ProcessKnown
|
NCR_ProcessKnown
|
||||||
(NTP_Packet *message, /* the received message */
|
(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,
|
double now_err,
|
||||||
NCR_Instance inst, /* the instance record for this peer/server */
|
NCR_Instance inst, /* the instance record for this peer/server */
|
||||||
NTP_Local_Address *local_addr, /* the receiving address */
|
NTP_Local_Address *local_addr, /* the receiving address */
|
||||||
|
@ -1681,7 +1679,7 @@ NCR_ProcessKnown
|
||||||
void
|
void
|
||||||
NCR_ProcessUnknown
|
NCR_ProcessUnknown
|
||||||
(NTP_Packet *message, /* the received message */
|
(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 */
|
double now_err, /* assumed error in the timestamp */
|
||||||
NTP_Remote_Address *remote_addr,
|
NTP_Remote_Address *remote_addr,
|
||||||
NTP_Local_Address *local_addr,
|
NTP_Local_Address *local_addr,
|
||||||
|
@ -1768,14 +1766,14 @@ NCR_ProcessUnknown
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
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;
|
double delta;
|
||||||
|
|
||||||
if (inst->local_rx.tv_sec || inst->local_rx.tv_usec)
|
if (inst->local_rx.tv_sec || inst->local_rx.tv_nsec)
|
||||||
UTI_AdjustTimeval(&inst->local_rx, when, &inst->local_rx, &delta, dfreq, doffset);
|
UTI_AdjustTimespec(&inst->local_rx, when, &inst->local_rx, &delta, dfreq, doffset);
|
||||||
if (inst->local_tx.tv_sec || inst->local_tx.tv_usec)
|
if (inst->local_tx.tv_sec || inst->local_tx.tv_nsec)
|
||||||
UTI_AdjustTimeval(&inst->local_tx, when, &inst->local_tx, &delta, dfreq, doffset);
|
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
|
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;
|
report->poll = inst->local_poll;
|
||||||
|
|
||||||
|
@ -2073,14 +2071,13 @@ broadcast_timeout(void *arg)
|
||||||
{
|
{
|
||||||
BroadcastDestination *destination;
|
BroadcastDestination *destination;
|
||||||
NTP_int64 orig_ts;
|
NTP_int64 orig_ts;
|
||||||
struct timeval recv_ts;
|
struct timespec recv_ts;
|
||||||
|
|
||||||
destination = ARR_GetElement(broadcasts, (long)arg);
|
destination = ARR_GetElement(broadcasts, (long)arg);
|
||||||
|
|
||||||
orig_ts.hi = 0;
|
orig_ts.hi = 0;
|
||||||
orig_ts.lo = 0;
|
orig_ts.lo = 0;
|
||||||
recv_ts.tv_sec = 0;
|
UTI_ZeroTimespec(&recv_ts);
|
||||||
recv_ts.tv_usec = 0;
|
|
||||||
|
|
||||||
transmit_packet(MODE_BROADCAST, 6 /* FIXME: should this be log2(interval)? */,
|
transmit_packet(MODE_BROADCAST, 6 /* FIXME: should this be log2(interval)? */,
|
||||||
NTP_VERSION, 0, 0, &orig_ts, &recv_ts, NULL, NULL,
|
NTP_VERSION, 0, 0, &orig_ts, &recv_ts, NULL, NULL,
|
||||||
|
|
|
@ -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,
|
/* 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 */
|
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,
|
/* This routine is called when a new packet arrives off the network,
|
||||||
and we do not recognize its source */
|
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 */
|
/* 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) */
|
/* Take a particular source online (i.e. start sampling it) */
|
||||||
extern void NCR_TakeSourceOnline(NCR_Instance inst);
|
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_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_AddAccessRestriction(IPAddr *ip_addr, int subnet_bits, int allow, int all);
|
||||||
extern int NCR_CheckAccessRestriction(IPAddr *ip_addr);
|
extern int NCR_CheckAccessRestriction(IPAddr *ip_addr);
|
||||||
|
|
6
ntp_io.c
6
ntp_io.c
|
@ -549,7 +549,7 @@ process_receive(struct msghdr *hdr, int length, int sock_fd)
|
||||||
NTP_Remote_Address remote_addr;
|
NTP_Remote_Address remote_addr;
|
||||||
NTP_Local_Address local_addr;
|
NTP_Local_Address local_addr;
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
double now_err;
|
double now_err;
|
||||||
|
|
||||||
SCH_GetLastEventTime(&now, &now_err, NULL);
|
SCH_GetLastEventTime(&now, &now_err, NULL);
|
||||||
|
@ -590,9 +590,11 @@ process_receive(struct msghdr *hdr, int length, int sock_fd)
|
||||||
#ifdef SO_TIMESTAMP
|
#ifdef SO_TIMESTAMP
|
||||||
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
|
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) {
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));
|
memcpy(&tv, CMSG_DATA(cmsg), sizeof(tv));
|
||||||
LCL_CookTime(&tv, &now, &now_err);
|
UTI_TimevalToTimespec(&tv, &ts);
|
||||||
|
LCL_CookTime(&ts, &now, &now_err);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
12
ntp_signd.c
12
ntp_signd.c
|
@ -73,7 +73,7 @@ typedef struct {
|
||||||
int sent;
|
int sent;
|
||||||
int received;
|
int received;
|
||||||
int request_length;
|
int request_length;
|
||||||
struct timeval request_tv;
|
struct timespec request_ts;
|
||||||
SigndRequest request;
|
SigndRequest request;
|
||||||
SigndResponse response;
|
SigndResponse response;
|
||||||
} SignInstance;
|
} SignInstance;
|
||||||
|
@ -166,7 +166,7 @@ open_socket(void)
|
||||||
static void
|
static void
|
||||||
process_response(SignInstance *inst)
|
process_response(SignInstance *inst)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timespec ts;
|
||||||
double delay;
|
double delay;
|
||||||
|
|
||||||
if (ntohs(inst->request.packet_id) != ntohl(inst->response.packet_id)) {
|
if (ntohs(inst->request.packet_id) != ntohl(inst->response.packet_id)) {
|
||||||
|
@ -185,8 +185,8 @@ process_response(SignInstance *inst)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCH_GetLastEventTime(NULL, NULL, &tv);
|
SCH_GetLastEventTime(NULL, NULL, &ts);
|
||||||
UTI_DiffTimevalsToDouble(&delay, &tv, &inst->request_tv);
|
UTI_DiffTimespecsToDouble(&delay, &ts, &inst->request_ts);
|
||||||
|
|
||||||
DEBUG_LOG(LOGF_NtpSignd, "Signing succeeded (delay %f)", delay);
|
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);
|
assert(inst->sent < inst->request_length);
|
||||||
|
|
||||||
if (!inst->sent)
|
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,
|
s = send(sock_fd, (char *)&inst->request + inst->sent,
|
||||||
inst->request_length - inst->sent, 0);
|
inst->request_length - inst->sent, 0);
|
||||||
|
@ -322,7 +322,7 @@ NSD_Finalise()
|
||||||
|
|
||||||
extern int NSD_GetAuthDelay(uint32_t key_id)
|
extern int NSD_GetAuthDelay(uint32_t key_id)
|
||||||
{
|
{
|
||||||
return auth_delay * 1.0e6;
|
return 1.0e9 * auth_delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
|
@ -117,8 +117,8 @@ static void rehash_records(void);
|
||||||
static void clean_source_record(SourceRecord *record);
|
static void clean_source_record(SourceRecord *record);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
slew_sources(struct timeval *raw,
|
slew_sources(struct timespec *raw,
|
||||||
struct timeval *cooked,
|
struct timespec *cooked,
|
||||||
double dfreq,
|
double dfreq,
|
||||||
double doffset,
|
double doffset,
|
||||||
LCL_ChangeType change_type,
|
LCL_ChangeType change_type,
|
||||||
|
@ -680,8 +680,8 @@ resolve_source_replacement(SourceRecord *record)
|
||||||
void
|
void
|
||||||
NSR_HandleBadSource(IPAddr *address)
|
NSR_HandleBadSource(IPAddr *address)
|
||||||
{
|
{
|
||||||
static struct timeval last_replacement;
|
static struct timespec last_replacement;
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
NTP_Remote_Address remote_addr;
|
NTP_Remote_Address remote_addr;
|
||||||
SourceRecord *record;
|
SourceRecord *record;
|
||||||
int slot, found;
|
int slot, found;
|
||||||
|
@ -702,7 +702,7 @@ NSR_HandleBadSource(IPAddr *address)
|
||||||
|
|
||||||
/* Don't resolve names too frequently */
|
/* Don't resolve names too frequently */
|
||||||
SCH_GetLastEventTime(NULL, NULL, &now);
|
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)) {
|
if (fabs(diff) < RESOLVE_INTERVAL_UNIT * (1 << MIN_REPLACEMENT_INTERVAL)) {
|
||||||
DEBUG_LOG(LOGF_NtpSources, "replacement postponed");
|
DEBUG_LOG(LOGF_NtpSources, "replacement postponed");
|
||||||
return;
|
return;
|
||||||
|
@ -776,7 +776,7 @@ NSR_GetLocalRefid(IPAddr *address)
|
||||||
/* This routine is called by ntp_io when a new packet arrives off the network,
|
/* This routine is called by ntp_io when a new packet arrives off the network,
|
||||||
possibly with an authentication tail */
|
possibly with an authentication tail */
|
||||||
void
|
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;
|
SourceRecord *record;
|
||||||
struct SourcePool *pool;
|
struct SourcePool *pool;
|
||||||
|
@ -816,8 +816,8 @@ NSR_ProcessReceive(NTP_Packet *message, struct timeval *now, double now_err, NTP
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
slew_sources(struct timeval *raw,
|
slew_sources(struct timespec *raw,
|
||||||
struct timeval *cooked,
|
struct timespec *cooked,
|
||||||
double dfreq,
|
double dfreq,
|
||||||
double doffset,
|
double doffset,
|
||||||
LCL_ChangeType change_type,
|
LCL_ChangeType change_type,
|
||||||
|
@ -1083,7 +1083,7 @@ NSR_InitiateSampleBurst(int n_good_samples, int n_total_samples,
|
||||||
identify the source record. */
|
identify the source record. */
|
||||||
|
|
||||||
void
|
void
|
||||||
NSR_ReportSource(RPT_SourceReport *report, struct timeval *now)
|
NSR_ReportSource(RPT_SourceReport *report, struct timespec *now)
|
||||||
{
|
{
|
||||||
NTP_Remote_Address rem_addr;
|
NTP_Remote_Address rem_addr;
|
||||||
int slot, found;
|
int slot, found;
|
||||||
|
|
|
@ -87,7 +87,7 @@ extern void NSR_RefreshAddresses(void);
|
||||||
extern uint32_t NSR_GetLocalRefid(IPAddr *address);
|
extern uint32_t NSR_GetLocalRefid(IPAddr *address);
|
||||||
|
|
||||||
/* This routine is called by ntp_io when a new packet arrives off the network */
|
/* 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 */
|
/* Initialisation function */
|
||||||
extern void NSR_Initialise(void);
|
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 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);
|
extern void NSR_GetActivityReport(RPT_ActivityReport *report);
|
||||||
|
|
||||||
|
|
82
refclock.c
82
refclock.c
|
@ -48,7 +48,7 @@ extern RefclockDriver RCL_PHC_driver;
|
||||||
struct FilterSample {
|
struct FilterSample {
|
||||||
double offset;
|
double offset;
|
||||||
double dispersion;
|
double dispersion;
|
||||||
struct timeval sample_time;
|
struct timespec sample_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MedianFilter {
|
struct MedianFilter {
|
||||||
|
@ -92,23 +92,23 @@ static ARR_Instance refclocks;
|
||||||
|
|
||||||
static LOG_FileID logfileid;
|
static LOG_FileID logfileid;
|
||||||
|
|
||||||
static int valid_sample_time(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 timeval *tv);
|
static int pps_stratum(RCL_Instance instance, struct timespec *ts);
|
||||||
static void poll_timeout(void *arg);
|
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);
|
double doffset, LCL_ChangeType change_type, void *anything);
|
||||||
static void add_dispersion(double dispersion, 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_init(struct MedianFilter *filter, int length, double max_dispersion);
|
||||||
static void filter_fini(struct MedianFilter *filter);
|
static void filter_fini(struct MedianFilter *filter);
|
||||||
static void filter_reset(struct MedianFilter *filter);
|
static void filter_reset(struct MedianFilter *filter);
|
||||||
static double filter_get_avg_sample_dispersion(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 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 timeval *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_select_samples(struct MedianFilter *filter);
|
||||||
static int filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, double *offset, double *dispersion);
|
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 timeval *when, double dfreq, double doffset);
|
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 void filter_add_dispersion(struct MedianFilter *filter, double dispersion);
|
||||||
|
|
||||||
static RCL_Instance
|
static RCL_Instance
|
||||||
|
@ -299,7 +299,7 @@ RCL_StartRefclocks(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
|
RCL_ReportSource(RPT_SourceReport *report, struct timespec *now)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
uint32_t ref_id;
|
uint32_t ref_id;
|
||||||
|
@ -361,13 +361,13 @@ RCL_GetDriverOption(RCL_Instance instance, char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
double correction, dispersion;
|
||||||
struct timeval cooked_time;
|
struct timespec cooked_time;
|
||||||
|
|
||||||
LCL_GetOffsetCorrection(sample_time, &correction, &dispersion);
|
LCL_GetOffsetCorrection(sample_time, &correction, &dispersion);
|
||||||
UTI_AddDoubleToTimeval(sample_time, correction, &cooked_time);
|
UTI_AddDoubleToTimespec(sample_time, correction, &cooked_time);
|
||||||
dispersion += instance->precision;
|
dispersion += instance->precision;
|
||||||
|
|
||||||
/* Make sure the timestamp and offset provided by the driver are sane */
|
/* 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
|
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;
|
double correction, dispersion, offset;
|
||||||
struct timeval cooked_time;
|
struct timespec cooked_time;
|
||||||
int rate;
|
int rate;
|
||||||
NTP_Leap leap;
|
NTP_Leap leap;
|
||||||
|
|
||||||
leap = LEAP_Normal;
|
leap = LEAP_Normal;
|
||||||
LCL_GetOffsetCorrection(pulse_time, &correction, &dispersion);
|
LCL_GetOffsetCorrection(pulse_time, &correction, &dispersion);
|
||||||
UTI_AddDoubleToTimeval(pulse_time, correction, &cooked_time);
|
UTI_AddDoubleToTimespec(pulse_time, correction, &cooked_time);
|
||||||
dispersion += instance->precision;
|
dispersion += instance->precision;
|
||||||
|
|
||||||
if (!UTI_IsTimeOffsetSane(pulse_time, 0.0) ||
|
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) {
|
if (instance->lock_ref != -1) {
|
||||||
RCL_Instance lock_refclock;
|
RCL_Instance lock_refclock;
|
||||||
struct timeval ref_sample_time;
|
struct timespec ref_sample_time;
|
||||||
double sample_diff, ref_offset, ref_dispersion, shift;
|
double sample_diff, ref_offset, ref_dispersion, shift;
|
||||||
|
|
||||||
lock_refclock = get_refclock(instance->lock_ref);
|
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);
|
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) {
|
if (fabs(sample_diff) >= 2.0 / rate) {
|
||||||
DEBUG_LOG(LOGF_Refclock, "refclock pulse ignored samplediff=%.9f",
|
DEBUG_LOG(LOGF_Refclock, "refclock pulse ignored samplediff=%.9f",
|
||||||
sample_diff);
|
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",
|
DEBUG_LOG(LOGF_Refclock, "refclock pulse second=%.9f offset=%.9f offdiff=%.9f samplediff=%.9f",
|
||||||
second, offset, ref_offset - offset, sample_diff);
|
second, offset, ref_offset - offset, sample_diff);
|
||||||
} else {
|
} else {
|
||||||
struct timeval ref_time;
|
struct timespec ref_time;
|
||||||
int is_synchronised, stratum;
|
int is_synchronised, stratum;
|
||||||
double root_delay, root_dispersion, distance;
|
double root_delay, root_dispersion, distance;
|
||||||
uint32_t ref_id;
|
uint32_t ref_id;
|
||||||
|
@ -503,25 +503,25 @@ RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
double diff;
|
||||||
|
|
||||||
LCL_ReadRawTime(&raw_time);
|
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)) {
|
if (diff < 0.0 || diff > UTI_Log2ToDouble(instance->poll + 1)) {
|
||||||
DEBUG_LOG(LOGF_Refclock, "%s refclock sample not valid age=%.6f tv=%s",
|
DEBUG_LOG(LOGF_Refclock, "%s refclock sample not valid age=%.6f ts=%s",
|
||||||
UTI_RefidToString(instance->ref_id), diff, UTI_TimevalToString(tv));
|
UTI_RefidToString(instance->ref_id), diff, UTI_TimespecToString(ts));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
int is_synchronised, stratum;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
double root_delay, root_dispersion;
|
double root_delay, root_dispersion;
|
||||||
|
@ -529,7 +529,7 @@ pps_stratum(RCL_Instance instance, struct timeval *tv)
|
||||||
uint32_t ref_id;
|
uint32_t ref_id;
|
||||||
RCL_Instance refclock;
|
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);
|
&ref_id, &ref_time, &root_delay, &root_dispersion);
|
||||||
|
|
||||||
/* Don't change our stratum if the local reference is active
|
/* 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)))) {
|
if (!(inst->driver->poll && inst->driver_polled < (1 << (inst->poll - inst->driver_poll)))) {
|
||||||
double offset, dispersion;
|
double offset, dispersion;
|
||||||
struct timeval sample_time;
|
struct timespec sample_time;
|
||||||
int sample_ok, stratum;
|
int sample_ok, stratum;
|
||||||
|
|
||||||
sample_ok = filter_get_sample(&inst->filter, &sample_time, &offset, &dispersion);
|
sample_ok = filter_get_sample(&inst->filter, &sample_time, &offset, &dispersion);
|
||||||
|
@ -594,7 +594,7 @@ poll_timeout(void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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)
|
double doffset, LCL_ChangeType change_type, void *anything)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -617,7 +617,7 @@ add_dispersion(double dispersion, void *anything)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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', '+', '-', '?'};
|
char sync_stats[4] = {'N', '+', '-', '?'};
|
||||||
|
|
||||||
|
@ -627,7 +627,7 @@ log_sample(RCL_Instance instance, struct timeval *sample_time, int filtered, int
|
||||||
if (!filtered) {
|
if (!filtered) {
|
||||||
LOG_FileWrite(logfileid, "%s.%06d %-5s %3d %1c %1d %13.6e %13.6e %10.3e",
|
LOG_FileWrite(logfileid, "%s.%06d %-5s %3d %1c %1d %13.6e %13.6e %10.3e",
|
||||||
UTI_TimeToLogForm(sample_time->tv_sec),
|
UTI_TimeToLogForm(sample_time->tv_sec),
|
||||||
(int)sample_time->tv_usec,
|
(int)sample_time->tv_nsec / 1000,
|
||||||
UTI_RefidToString(instance->ref_id),
|
UTI_RefidToString(instance->ref_id),
|
||||||
instance->driver_polled,
|
instance->driver_polled,
|
||||||
sync_stats[instance->leap_status],
|
sync_stats[instance->leap_status],
|
||||||
|
@ -638,7 +638,7 @@ log_sample(RCL_Instance instance, struct timeval *sample_time, int filtered, int
|
||||||
} else {
|
} else {
|
||||||
LOG_FileWrite(logfileid, "%s.%06d %-5s - %1c - - %13.6e %10.3e",
|
LOG_FileWrite(logfileid, "%s.%06d %-5s - %1c - - %13.6e %10.3e",
|
||||||
UTI_TimeToLogForm(sample_time->tv_sec),
|
UTI_TimeToLogForm(sample_time->tv_sec),
|
||||||
(int)sample_time->tv_usec,
|
(int)sample_time->tv_nsec / 1000,
|
||||||
UTI_RefidToString(instance->ref_id),
|
UTI_RefidToString(instance->ref_id),
|
||||||
sync_stats[instance->leap_status],
|
sync_stats[instance->leap_status],
|
||||||
cooked_offset,
|
cooked_offset,
|
||||||
|
@ -691,7 +691,7 @@ filter_get_avg_sample_dispersion(struct MedianFilter *filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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->index %= filter->length;
|
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;
|
filter->samples[filter->index].dispersion = dispersion;
|
||||||
|
|
||||||
DEBUG_LOG(LOGF_Refclock, "filter sample %d t=%s offset=%.9f dispersion=%.9f",
|
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
|
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)
|
if (filter->last < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -821,7 +821,7 @@ filter_select_samples(struct MedianFilter *filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
struct FilterSample *s, *ls;
|
||||||
int i, n, dof;
|
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++) {
|
for (i = 0; i < n; i++) {
|
||||||
s = &filter->samples[filter->selected[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->y_data[i] = s->offset;
|
||||||
filter->w_data[i] = s->dispersion;
|
filter->w_data[i] = s->dispersion;
|
||||||
}
|
}
|
||||||
|
@ -913,7 +913,7 @@ filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, doub
|
||||||
if (d < e)
|
if (d < e)
|
||||||
d = e;
|
d = e;
|
||||||
|
|
||||||
UTI_AddDoubleToTimeval(&ls->sample_time, x, sample_time);
|
UTI_AddDoubleToTimespec(&ls->sample_time, x, sample_time);
|
||||||
*offset = y;
|
*offset = y;
|
||||||
*dispersion = d;
|
*dispersion = d;
|
||||||
|
|
||||||
|
@ -923,15 +923,15 @@ filter_get_sample(struct MedianFilter *filter, struct timeval *sample_time, doub
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
int i;
|
||||||
double delta_time;
|
double delta_time;
|
||||||
struct timeval *sample;
|
struct timespec *sample;
|
||||||
|
|
||||||
for (i = 0; i < filter->used; i++) {
|
for (i = 0; i < filter->used; i++) {
|
||||||
sample = &filter->samples[i].sample_time;
|
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;
|
filter->samples[i].offset -= delta_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,14 +61,14 @@ extern void RCL_Initialise(void);
|
||||||
extern void RCL_Finalise(void);
|
extern void RCL_Finalise(void);
|
||||||
extern int RCL_AddRefclock(RefclockParameters *params);
|
extern int RCL_AddRefclock(RefclockParameters *params);
|
||||||
extern void RCL_StartRefclocks(void);
|
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 */
|
/* functions used by drivers */
|
||||||
extern void RCL_SetDriverData(RCL_Instance instance, void *data);
|
extern void RCL_SetDriverData(RCL_Instance instance, void *data);
|
||||||
extern void *RCL_GetDriverData(RCL_Instance instance);
|
extern void *RCL_GetDriverData(RCL_Instance instance);
|
||||||
extern char *RCL_GetDriverParameter(RCL_Instance instance);
|
extern char *RCL_GetDriverParameter(RCL_Instance instance);
|
||||||
extern char *RCL_GetDriverOption(RCL_Instance instance, char *name);
|
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_AddSample(RCL_Instance instance, struct timespec *sample_time, double offset, int leap);
|
||||||
extern int RCL_AddPulse(RCL_Instance instance, struct timeval *pulse_time, double second);
|
extern int RCL_AddPulse(RCL_Instance instance, struct timespec *pulse_time, double second);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -56,11 +56,6 @@ struct phc_reading {
|
||||||
struct timespec sys_ts2;
|
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)
|
static int read_phc_ioctl(struct phc_reading *readings, int phc_fd, int n)
|
||||||
{
|
{
|
||||||
#if defined(PTP_SYS_OFFSET) && NUM_READINGS <= PTP_MAX_SAMPLES
|
#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)
|
static int phc_poll(RCL_Instance instance)
|
||||||
{
|
{
|
||||||
struct phc_reading readings[NUM_READINGS];
|
struct phc_reading readings[NUM_READINGS];
|
||||||
struct timeval tv;
|
|
||||||
double offset = 0.0, delay, best_delay = 0.0;
|
double offset = 0.0, delay, best_delay = 0.0;
|
||||||
int i, phc_fd, best;
|
int i, phc_fd, best;
|
||||||
|
|
||||||
|
@ -163,7 +157,7 @@ static int phc_poll(RCL_Instance instance)
|
||||||
|
|
||||||
/* Find the fastest reading */
|
/* Find the fastest reading */
|
||||||
for (i = 0; i < NUM_READINGS; i++) {
|
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) {
|
if (!i || best_delay > delay) {
|
||||||
best = i;
|
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;
|
UTI_DiffTimespecsToDouble(&offset, &readings[best].phc_ts, &readings[best].sys_ts2);
|
||||||
tv.tv_sec = readings[best].sys_ts2.tv_sec;
|
offset += best_delay / 2.0;
|
||||||
tv.tv_usec = readings[best].sys_ts2.tv_nsec / 1000;
|
|
||||||
|
|
||||||
DEBUG_LOG(LOGF_Refclock, "PHC offset: %+.9f delay: %.9f", offset, best_delay);
|
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 = {
|
RefclockDriver RCL_PHC_driver = {
|
||||||
|
|
|
@ -124,7 +124,6 @@ static int pps_poll(RCL_Instance instance)
|
||||||
{
|
{
|
||||||
struct pps_instance *pps;
|
struct pps_instance *pps;
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
struct timeval tv;
|
|
||||||
pps_info_t pps_info;
|
pps_info_t pps_info;
|
||||||
pps_seq_t seq;
|
pps_seq_t seq;
|
||||||
|
|
||||||
|
@ -153,10 +152,8 @@ static int pps_poll(RCL_Instance instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
pps->last_seq = seq;
|
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 = {
|
RefclockDriver RCL_PPS_driver = {
|
||||||
|
|
|
@ -90,7 +90,7 @@ static void shm_finalise(RCL_Instance instance)
|
||||||
|
|
||||||
static int shm_poll(RCL_Instance instance)
|
static int shm_poll(RCL_Instance instance)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timespec receive_ts, clock_ts;
|
||||||
struct shmTime t, *shm;
|
struct shmTime t, *shm;
|
||||||
double offset;
|
double offset;
|
||||||
|
|
||||||
|
@ -107,17 +107,23 @@ static int shm_poll(RCL_Instance instance)
|
||||||
|
|
||||||
shm->valid = 0;
|
shm->valid = 0;
|
||||||
|
|
||||||
tv.tv_sec = t.receiveTimeStampSec;
|
receive_ts.tv_sec = t.receiveTimeStampSec;
|
||||||
tv.tv_usec = t.receiveTimeStampUSec;
|
clock_ts.tv_sec = t.clockTimeStampSec;
|
||||||
|
|
||||||
offset = t.clockTimeStampSec - t.receiveTimeStampSec;
|
|
||||||
if (t.clockTimeStampNSec / 1000 == t.clockTimeStampUSec &&
|
if (t.clockTimeStampNSec / 1000 == t.clockTimeStampUSec &&
|
||||||
t.receiveTimeStampNSec / 1000 == t.receiveTimeStampUSec)
|
t.receiveTimeStampNSec / 1000 == t.receiveTimeStampUSec) {
|
||||||
offset += (t.clockTimeStampNSec - t.receiveTimeStampNSec) * 1e-9;
|
receive_ts.tv_nsec = t.receiveTimeStampNSec;
|
||||||
else
|
clock_ts.tv_nsec = t.clockTimeStampNSec;
|
||||||
offset += (t.clockTimeStampUSec - t.receiveTimeStampUSec) * 1e-6;
|
} 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 = {
|
RefclockDriver RCL_SHM_driver = {
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct sock_sample {
|
||||||
static void read_sample(int sockfd, int event, void *anything)
|
static void read_sample(int sockfd, int event, void *anything)
|
||||||
{
|
{
|
||||||
struct sock_sample sample;
|
struct sock_sample sample;
|
||||||
|
struct timespec ts;
|
||||||
RCL_Instance instance;
|
RCL_Instance instance;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
|
@ -85,10 +86,13 @@ static void read_sample(int sockfd, int event, void *anything)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UTI_TimevalToTimespec(&sample.tv, &ts);
|
||||||
|
UTI_NormaliseTimespec(&ts);
|
||||||
|
|
||||||
if (sample.pulse) {
|
if (sample.pulse) {
|
||||||
RCL_AddPulse(instance, &sample.tv, sample.offset);
|
RCL_AddPulse(instance, &ts, sample.offset);
|
||||||
} else {
|
} else {
|
||||||
RCL_AddSample(instance, &sample.tv, sample.offset, sample.leap);
|
RCL_AddSample(instance, &ts, sample.offset, sample.leap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
68
reference.c
68
reference.c
|
@ -52,7 +52,7 @@ static int our_leap_sec;
|
||||||
static int our_stratum;
|
static int our_stratum;
|
||||||
static uint32_t our_ref_id;
|
static uint32_t our_ref_id;
|
||||||
static IPAddr our_ref_ip;
|
static IPAddr our_ref_ip;
|
||||||
struct timeval our_ref_time;
|
struct timespec our_ref_time;
|
||||||
static double our_skew;
|
static double our_skew;
|
||||||
static double our_residual_freq;
|
static double our_residual_freq;
|
||||||
static double our_root_delay;
|
static double our_root_delay;
|
||||||
|
@ -136,7 +136,7 @@ static int next_fb_drift;
|
||||||
static SCH_TimeoutID fb_drift_timeout_id;
|
static SCH_TimeoutID fb_drift_timeout_id;
|
||||||
|
|
||||||
/* Timestamp of last reference update */
|
/* Timestamp of last reference update */
|
||||||
static struct timeval last_ref_update;
|
static struct timespec last_ref_update;
|
||||||
static double last_ref_update_interval;
|
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
|
static void
|
||||||
handle_slew(struct timeval *raw,
|
handle_slew(struct timespec *raw,
|
||||||
struct timeval *cooked,
|
struct timespec *cooked,
|
||||||
double dfreq,
|
double dfreq,
|
||||||
double doffset,
|
double doffset,
|
||||||
LCL_ChangeType change_type,
|
LCL_ChangeType change_type,
|
||||||
void *anything)
|
void *anything)
|
||||||
{
|
{
|
||||||
double delta;
|
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) {
|
if (change_type == LCL_ChangeUnknownStep) {
|
||||||
last_ref_update.tv_sec = 0;
|
UTI_ZeroTimespec(&last_ref_update);
|
||||||
last_ref_update.tv_usec = 0;
|
|
||||||
} else if (last_ref_update.tv_sec) {
|
} 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
|
/* 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;
|
fb_drift_timeout_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_ref_update.tv_sec = 0;
|
UTI_ZeroTimespec(&last_ref_update);
|
||||||
last_ref_update.tv_usec = 0;
|
|
||||||
last_ref_update_interval = 0.0;
|
last_ref_update_interval = 0.0;
|
||||||
|
|
||||||
LCL_AddParameterChangeHandler(handle_slew, NULL);
|
LCL_AddParameterChangeHandler(handle_slew, NULL);
|
||||||
|
@ -468,16 +466,16 @@ fb_drift_timeout(void *arg)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
schedule_fb_drift(struct timeval *now)
|
schedule_fb_drift(struct timespec *now)
|
||||||
{
|
{
|
||||||
int i, c, secs;
|
int i, c, secs;
|
||||||
double unsynchronised;
|
double unsynchronised;
|
||||||
struct timeval when;
|
struct timespec when;
|
||||||
|
|
||||||
if (fb_drift_timeout_id)
|
if (fb_drift_timeout_id)
|
||||||
return; /* already scheduled */
|
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++) {
|
for (c = secs = 0, i = fb_drift_min; i <= fb_drift_max; i++) {
|
||||||
secs = 1 << i;
|
secs = 1 << i;
|
||||||
|
@ -499,7 +497,7 @@ schedule_fb_drift(struct timeval *now)
|
||||||
|
|
||||||
if (i <= fb_drift_max) {
|
if (i <= fb_drift_max) {
|
||||||
next_fb_drift = i;
|
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);
|
fb_drift_timeout_id = SCH_AddTimeout(&when, fb_drift_timeout, NULL);
|
||||||
DEBUG_LOG(LOGF_Reference, "Fallback drift %d scheduled", i);
|
DEBUG_LOG(LOGF_Reference, "Fallback drift %d scheduled", i);
|
||||||
}
|
}
|
||||||
|
@ -727,7 +725,7 @@ leap_start_timeout(void *arg)
|
||||||
static void
|
static void
|
||||||
set_leap_timeout(time_t now)
|
set_leap_timeout(time_t now)
|
||||||
{
|
{
|
||||||
struct timeval when;
|
struct timespec when;
|
||||||
|
|
||||||
/* Stop old timer if there is one */
|
/* Stop old timer if there is one */
|
||||||
SCH_RemoveTimeout(leap_timeout_id);
|
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 be corrected by the system, timeout slightly sooner to be sure it
|
||||||
will happen before the system correction. */
|
will happen before the system correction. */
|
||||||
when.tv_sec = (now / (24 * 3600) + 1) * (24 * 3600);
|
when.tv_sec = (now / (24 * 3600) + 1) * (24 * 3600);
|
||||||
when.tv_usec = 0;
|
when.tv_nsec = 0;
|
||||||
if (our_leap_sec < 0)
|
if (our_leap_sec < 0)
|
||||||
when.tv_sec--;
|
when.tv_sec--;
|
||||||
if (leap_mode == REF_LeapModeSystem) {
|
if (leap_mode == REF_LeapModeSystem) {
|
||||||
when.tv_sec--;
|
when.tv_sec--;
|
||||||
when.tv_usec = 500000;
|
when.tv_nsec = 500000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
leap_timeout_id = SCH_AddTimeout(&when, leap_start_timeout, NULL);
|
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
|
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 freq, double skew, double offset, int combined_sources,
|
||||||
double offset_sd, double uncorrected_offset)
|
double offset_sd, double uncorrected_offset)
|
||||||
{
|
{
|
||||||
|
@ -881,7 +879,7 @@ REF_SetReference(int stratum,
|
||||||
int combined_sources,
|
int combined_sources,
|
||||||
uint32_t ref_id,
|
uint32_t ref_id,
|
||||||
IPAddr *ref_ip,
|
IPAddr *ref_ip,
|
||||||
struct timeval *ref_time,
|
struct timespec *ref_time,
|
||||||
double offset,
|
double offset,
|
||||||
double offset_sd,
|
double offset_sd,
|
||||||
double frequency,
|
double frequency,
|
||||||
|
@ -902,7 +900,7 @@ REF_SetReference(int stratum,
|
||||||
double elapsed;
|
double elapsed;
|
||||||
double correction_rate;
|
double correction_rate;
|
||||||
double uncorrected_offset, accumulate_offset, step_offset;
|
double uncorrected_offset, accumulate_offset, step_offset;
|
||||||
struct timeval now, raw_now;
|
struct timespec now, raw_now;
|
||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
|
@ -936,9 +934,9 @@ REF_SetReference(int stratum,
|
||||||
|
|
||||||
LCL_ReadRawTime(&raw_now);
|
LCL_ReadRawTime(&raw_now);
|
||||||
LCL_GetOffsetCorrection(&raw_now, &uncorrected_offset, NULL);
|
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;
|
our_offset = offset + elapsed * frequency;
|
||||||
|
|
||||||
if (!is_offset_ok(our_offset))
|
if (!is_offset_ok(our_offset))
|
||||||
|
@ -956,7 +954,7 @@ REF_SetReference(int stratum,
|
||||||
our_root_dispersion = root_dispersion;
|
our_root_dispersion = root_dispersion;
|
||||||
|
|
||||||
if (last_ref_update.tv_sec) {
|
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)
|
if (update_interval < 0.0)
|
||||||
update_interval = 0.0;
|
update_interval = 0.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1089,7 +1087,7 @@ REF_SetReference(int stratum,
|
||||||
void
|
void
|
||||||
REF_SetManualReference
|
REF_SetManualReference
|
||||||
(
|
(
|
||||||
struct timeval *ref_time,
|
struct timespec *ref_time,
|
||||||
double offset,
|
double offset,
|
||||||
double frequency,
|
double frequency,
|
||||||
double skew
|
double skew
|
||||||
|
@ -1108,7 +1106,7 @@ void
|
||||||
REF_SetUnsynchronised(void)
|
REF_SetUnsynchronised(void)
|
||||||
{
|
{
|
||||||
/* Variables required for logging to statistics log */
|
/* Variables required for logging to statistics log */
|
||||||
struct timeval now, now_raw;
|
struct timespec now, now_raw;
|
||||||
double uncorrected_offset;
|
double uncorrected_offset;
|
||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
@ -1121,7 +1119,7 @@ REF_SetUnsynchronised(void)
|
||||||
|
|
||||||
LCL_ReadRawTime(&now_raw);
|
LCL_ReadRawTime(&now_raw);
|
||||||
LCL_GetOffsetCorrection(&now_raw, &uncorrected_offset, NULL);
|
LCL_GetOffsetCorrection(&now_raw, &uncorrected_offset, NULL);
|
||||||
UTI_AddDoubleToTimeval(&now_raw, uncorrected_offset, &now);
|
UTI_AddDoubleToTimespec(&now_raw, uncorrected_offset, &now);
|
||||||
|
|
||||||
if (fb_drifts) {
|
if (fb_drifts) {
|
||||||
schedule_fb_drift(&now);
|
schedule_fb_drift(&now);
|
||||||
|
@ -1149,12 +1147,12 @@ REF_SetUnsynchronised(void)
|
||||||
void
|
void
|
||||||
REF_GetReferenceParams
|
REF_GetReferenceParams
|
||||||
(
|
(
|
||||||
struct timeval *local_time,
|
struct timespec *local_time,
|
||||||
int *is_synchronised,
|
int *is_synchronised,
|
||||||
NTP_Leap *leap_status,
|
NTP_Leap *leap_status,
|
||||||
int *stratum,
|
int *stratum,
|
||||||
uint32_t *ref_id,
|
uint32_t *ref_id,
|
||||||
struct timeval *ref_time,
|
struct timespec *ref_time,
|
||||||
double *root_delay,
|
double *root_delay,
|
||||||
double *root_dispersion
|
double *root_dispersion
|
||||||
)
|
)
|
||||||
|
@ -1164,7 +1162,7 @@ REF_GetReferenceParams
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
|
||||||
if (are_we_synchronised) {
|
if (are_we_synchronised) {
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, local_time, &our_ref_time);
|
UTI_DiffTimespecsToDouble(&elapsed, local_time, &our_ref_time);
|
||||||
dispersion = our_root_dispersion +
|
dispersion = our_root_dispersion +
|
||||||
(our_skew + fabs(our_residual_freq) + LCL_GetMaxClockError()) * elapsed;
|
(our_skew + fabs(our_residual_freq) + LCL_GetMaxClockError()) * elapsed;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1215,7 +1213,7 @@ REF_GetReferenceParams
|
||||||
*leap_status = LEAP_Unsynchronised;
|
*leap_status = LEAP_Unsynchronised;
|
||||||
*stratum = NTP_MAX_STRATUM;
|
*stratum = NTP_MAX_STRATUM;
|
||||||
*ref_id = NTP_REFID_UNSYNC;
|
*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
|
/* These values seem to be standard for a client, and
|
||||||
any peer or client of ours will ignore them anyway because
|
any peer or client of ours will ignore them anyway because
|
||||||
we don't claim to be synchronised */
|
we don't claim to be synchronised */
|
||||||
|
@ -1230,7 +1228,7 @@ REF_GetReferenceParams
|
||||||
int
|
int
|
||||||
REF_GetOurStratum(void)
|
REF_GetOurStratum(void)
|
||||||
{
|
{
|
||||||
struct timeval now_cooked, ref_time;
|
struct timespec now_cooked, ref_time;
|
||||||
int synchronised, stratum;
|
int synchronised, stratum;
|
||||||
NTP_Leap leap_status;
|
NTP_Leap leap_status;
|
||||||
uint32_t ref_id;
|
uint32_t ref_id;
|
||||||
|
@ -1303,7 +1301,7 @@ REF_DisableLocal(void)
|
||||||
|
|
||||||
int REF_IsLeapSecondClose(void)
|
int REF_IsLeapSecondClose(void)
|
||||||
{
|
{
|
||||||
struct timeval now, now_raw;
|
struct timespec now, now_raw;
|
||||||
time_t t;
|
time_t t;
|
||||||
|
|
||||||
if (!our_leap_sec)
|
if (!our_leap_sec)
|
||||||
|
@ -1327,13 +1325,13 @@ int REF_IsLeapSecondClose(void)
|
||||||
void
|
void
|
||||||
REF_GetTrackingReport(RPT_TrackingReport *rep)
|
REF_GetTrackingReport(RPT_TrackingReport *rep)
|
||||||
{
|
{
|
||||||
struct timeval now_raw, now_cooked;
|
struct timespec now_raw, now_cooked;
|
||||||
double correction;
|
double correction;
|
||||||
int synchronised;
|
int synchronised;
|
||||||
|
|
||||||
LCL_ReadRawTime(&now_raw);
|
LCL_ReadRawTime(&now_raw);
|
||||||
LCL_GetOffsetCorrection(&now_raw, &correction, NULL);
|
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,
|
REF_GetReferenceParams(&now_cooked, &synchronised,
|
||||||
&rep->leap_status, &rep->stratum,
|
&rep->leap_status, &rep->stratum,
|
||||||
|
|
|
@ -99,12 +99,12 @@ extern REF_LeapMode REF_GetLeapMode(void);
|
||||||
|
|
||||||
extern void REF_GetReferenceParams
|
extern void REF_GetReferenceParams
|
||||||
(
|
(
|
||||||
struct timeval *local_time,
|
struct timespec *local_time,
|
||||||
int *is_synchronised,
|
int *is_synchronised,
|
||||||
NTP_Leap *leap,
|
NTP_Leap *leap,
|
||||||
int *stratum,
|
int *stratum,
|
||||||
uint32_t *ref_id,
|
uint32_t *ref_id,
|
||||||
struct timeval *ref_time,
|
struct timespec *ref_time,
|
||||||
double *root_delay,
|
double *root_delay,
|
||||||
double *root_dispersion
|
double *root_dispersion
|
||||||
);
|
);
|
||||||
|
@ -140,7 +140,7 @@ extern void REF_SetReference
|
||||||
int combined_sources,
|
int combined_sources,
|
||||||
uint32_t ref_id,
|
uint32_t ref_id,
|
||||||
IPAddr *ref_ip,
|
IPAddr *ref_ip,
|
||||||
struct timeval *ref_time,
|
struct timespec *ref_time,
|
||||||
double offset,
|
double offset,
|
||||||
double offset_sd,
|
double offset_sd,
|
||||||
double frequency,
|
double frequency,
|
||||||
|
@ -151,7 +151,7 @@ extern void REF_SetReference
|
||||||
|
|
||||||
extern void REF_SetManualReference
|
extern void REF_SetManualReference
|
||||||
(
|
(
|
||||||
struct timeval *ref_time,
|
struct timespec *ref_time,
|
||||||
double offset,
|
double offset,
|
||||||
double frequency,
|
double frequency,
|
||||||
double skew
|
double skew
|
||||||
|
|
|
@ -53,7 +53,7 @@ typedef struct {
|
||||||
IPAddr ip_addr;
|
IPAddr ip_addr;
|
||||||
int stratum;
|
int stratum;
|
||||||
NTP_Leap leap_status;
|
NTP_Leap leap_status;
|
||||||
struct timeval ref_time;
|
struct timespec ref_time;
|
||||||
double current_correction;
|
double current_correction;
|
||||||
double last_offset;
|
double last_offset;
|
||||||
double rms_offset;
|
double rms_offset;
|
||||||
|
@ -79,7 +79,7 @@ typedef struct {
|
||||||
} RPT_SourcestatsReport;
|
} RPT_SourcestatsReport;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct timeval ref_time;
|
struct timespec ref_time;
|
||||||
unsigned short n_samples;
|
unsigned short n_samples;
|
||||||
unsigned short n_runs;
|
unsigned short n_runs;
|
||||||
unsigned long span_seconds;
|
unsigned long span_seconds;
|
||||||
|
@ -109,7 +109,7 @@ typedef struct {
|
||||||
} RPT_ServerStatsReport;
|
} RPT_ServerStatsReport;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct timeval when;
|
struct timespec when;
|
||||||
double slewed_offset;
|
double slewed_offset;
|
||||||
double orig_offset;
|
double orig_offset;
|
||||||
double residual;
|
double residual;
|
||||||
|
|
2
rtc.c
2
rtc.c
|
@ -98,7 +98,7 @@ get_driftfile_time(void)
|
||||||
static void
|
static void
|
||||||
apply_driftfile_time(time_t t)
|
apply_driftfile_time(time_t t)
|
||||||
{
|
{
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
|
|
||||||
LCL_ReadCookedTime(&now, NULL);
|
LCL_ReadCookedTime(&now, NULL);
|
||||||
|
|
||||||
|
|
40
rtc_linux.c
40
rtc_linux.c
|
@ -92,9 +92,8 @@ static double *rtc_trim = NULL;
|
||||||
static time_t rtc_ref;
|
static time_t rtc_ref;
|
||||||
|
|
||||||
|
|
||||||
/* System clock (gettimeofday) samples associated with the above
|
/* System clock samples associated with the above samples. */
|
||||||
samples. */
|
static struct timespec *system_times = NULL;
|
||||||
static struct timeval *system_times = NULL;
|
|
||||||
|
|
||||||
/* Number of samples currently stored. */
|
/* Number of samples currently stored. */
|
||||||
static int n_samples;
|
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_sec, rtc_sec + new_first, n_to_save * sizeof(time_t));
|
||||||
memmove(rtc_trim, rtc_trim + new_first, n_to_save * sizeof(double));
|
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;
|
n_samples = n_to_save;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +179,7 @@ discard_samples(int new_first)
|
||||||
#define NEW_FIRST_WHEN_FULL 4
|
#define NEW_FIRST_WHEN_FULL 4
|
||||||
|
|
||||||
static void
|
static void
|
||||||
accumulate_sample(time_t rtc, struct timeval *sys)
|
accumulate_sample(time_t rtc, struct timespec *sys)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (n_samples == MAX_SAMPLES) {
|
if (n_samples == MAX_SAMPLES) {
|
||||||
|
@ -225,7 +224,7 @@ run_regression(int new_sample,
|
||||||
for (i=0; i<n_samples; i++) {
|
for (i=0; i<n_samples; i++) {
|
||||||
rtc_rel[i] = rtc_trim[i] + (double)(rtc_sec[i] - rtc_ref);
|
rtc_rel[i] = rtc_trim[i] + (double)(rtc_sec[i] - rtc_ref);
|
||||||
offsets[i] = ((double) (rtc_ref - system_times[i].tv_sec) -
|
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]);
|
rtc_rel[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -262,7 +261,7 @@ run_regression(int new_sample,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
slew_samples
|
slew_samples
|
||||||
(struct timeval *raw, struct timeval *cooked,
|
(struct timespec *raw, struct timespec *cooked,
|
||||||
double dfreq,
|
double dfreq,
|
||||||
double doffset,
|
double doffset,
|
||||||
LCL_ChangeType change_type,
|
LCL_ChangeType change_type,
|
||||||
|
@ -278,7 +277,7 @@ slew_samples
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<n_samples; i++) {
|
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);
|
dfreq, doffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,7 +533,7 @@ RTC_Linux_Initialise(void)
|
||||||
{
|
{
|
||||||
rtc_sec = MallocArray(time_t, MAX_SAMPLES);
|
rtc_sec = MallocArray(time_t, MAX_SAMPLES);
|
||||||
rtc_trim = MallocArray(double, 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 details depending on configuration options */
|
||||||
setup_config();
|
setup_config();
|
||||||
|
@ -758,7 +757,7 @@ maybe_autotrim(void)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static 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;
|
double rtc_fast;
|
||||||
|
|
||||||
|
@ -791,7 +790,7 @@ process_reading(time_t rtc_time, struct timeval *system_time)
|
||||||
|
|
||||||
|
|
||||||
if (logfileid != -1) {
|
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",
|
LOG_FileWrite(logfileid, "%s %14.6f %1d %14.6f %12.3f %2d %2d %4d",
|
||||||
UTI_TimeToLogForm(system_time->tv_sec),
|
UTI_TimeToLogForm(system_time->tv_sec),
|
||||||
|
@ -809,7 +808,7 @@ read_from_device(int fd_, int event, void *any)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
unsigned long data;
|
unsigned long data;
|
||||||
struct timeval sys_time;
|
struct timespec sys_time;
|
||||||
struct rtc_time rtc_raw;
|
struct rtc_time rtc_raw;
|
||||||
struct tm rtc_tm;
|
struct tm rtc_tm;
|
||||||
time_t rtc_t;
|
time_t rtc_t;
|
||||||
|
@ -849,7 +848,7 @@ read_from_device(int fd_, int event, void *any)
|
||||||
goto turn_off_interrupt;
|
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_sec = rtc_raw.tm_sec;
|
||||||
rtc_tm.tm_min = rtc_raw.tm_min;
|
rtc_tm.tm_min = rtc_raw.tm_min;
|
||||||
rtc_tm.tm_hour = rtc_raw.tm_hour;
|
rtc_tm.tm_hour = rtc_raw.tm_hour;
|
||||||
|
@ -978,7 +977,7 @@ RTC_Linux_TimePreInit(time_t driftfile_time)
|
||||||
struct tm rtc_tm;
|
struct tm rtc_tm;
|
||||||
time_t rtc_t;
|
time_t rtc_t;
|
||||||
double accumulated_error, sys_offset;
|
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();
|
coefs_file_name = CNF_GetRtcFile();
|
||||||
|
|
||||||
|
@ -1032,16 +1031,16 @@ RTC_Linux_TimePreInit(time_t driftfile_time)
|
||||||
|
|
||||||
new_sys_time.tv_sec = rtc_t;
|
new_sys_time.tv_sec = rtc_t;
|
||||||
/* Average error in the RTC reading */
|
/* 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) {
|
if (new_sys_time.tv_sec < driftfile_time) {
|
||||||
LOG(LOGS_WARN, LOGF_RtcLinux, "RTC time before last driftfile modification (ignored)");
|
LOG(LOGS_WARN, LOGF_RtcLinux, "RTC time before last driftfile modification (ignored)");
|
||||||
return 0;
|
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 */
|
/* Set system time only if the step is larger than 1 second */
|
||||||
if (fabs(sys_offset) >= 1.0) {
|
if (fabs(sys_offset) >= 1.0) {
|
||||||
|
@ -1064,7 +1063,7 @@ int
|
||||||
RTC_Linux_GetReport(RPT_RTC_Report *report)
|
RTC_Linux_GetReport(RPT_RTC_Report *report)
|
||||||
{
|
{
|
||||||
report->ref_time.tv_sec = coef_ref_time;
|
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_samples = n_samples;
|
||||||
report->n_runs = n_runs;
|
report->n_runs = n_runs;
|
||||||
if (n_samples > 1) {
|
if (n_samples > 1) {
|
||||||
|
@ -1083,8 +1082,7 @@ RTC_Linux_GetReport(RPT_RTC_Report *report)
|
||||||
int
|
int
|
||||||
RTC_Linux_Trim(void)
|
RTC_Linux_Trim(void)
|
||||||
{
|
{
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
|
|
||||||
|
|
||||||
/* Remember the slope coefficient - we won't be able to determine a
|
/* Remember the slope coefficient - we won't be able to determine a
|
||||||
good one in a few seconds when we determine the new offset! */
|
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
|
/* Estimate the offset in case writertc is called or chronyd
|
||||||
is terminated during rapid sampling */
|
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;
|
coef_ref_time = now.tv_sec;
|
||||||
|
|
||||||
/* And start rapid sampling, interrupts on now */
|
/* And start rapid sampling, interrupts on now */
|
||||||
|
|
80
sched.c
80
sched.c
|
@ -62,7 +62,7 @@ typedef struct {
|
||||||
static ARR_Instance file_handlers;
|
static ARR_Instance file_handlers;
|
||||||
|
|
||||||
/* Timestamp when last select() returned */
|
/* 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;
|
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 *next; /* Forward and back links in the list */
|
||||||
struct _TimerQueueEntry *prev;
|
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
|
timeout is to expire. Clearly this
|
||||||
must be in terms of what the
|
must be in terms of what the
|
||||||
operating system thinks of as
|
operating system thinks of as
|
||||||
|
@ -101,7 +101,7 @@ static SCH_TimeoutID next_tqe_id;
|
||||||
static TimerQueueEntry *tqe_free_list = NULL;
|
static TimerQueueEntry *tqe_free_list = NULL;
|
||||||
|
|
||||||
/* Timestamp when was last timeout dispatched for each class */
|
/* 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
|
static void
|
||||||
handle_slew(struct timeval *raw,
|
handle_slew(struct timespec *raw,
|
||||||
struct timeval *cooked,
|
struct timespec *cooked,
|
||||||
double dfreq,
|
double dfreq,
|
||||||
double doffset,
|
double doffset,
|
||||||
LCL_ChangeType change_type,
|
LCL_ChangeType change_type,
|
||||||
|
@ -231,7 +231,7 @@ SCH_SetFileHandlerEvents(int fd, int events)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
SCH_GetLastEventTime(struct timeval *cooked, double *err, struct timeval *raw)
|
SCH_GetLastEventTime(struct timespec *cooked, double *err, struct timespec *raw)
|
||||||
{
|
{
|
||||||
if (cooked) {
|
if (cooked) {
|
||||||
*cooked = last_select_ts;
|
*cooked = last_select_ts;
|
||||||
|
@ -298,7 +298,7 @@ try_again:
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
SCH_TimeoutID
|
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 *new_tqe;
|
||||||
TimerQueueEntry *ptr;
|
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->id = get_new_tqe_id();
|
||||||
new_tqe->handler = handler;
|
new_tqe->handler = handler;
|
||||||
new_tqe->arg = arg;
|
new_tqe->arg = arg;
|
||||||
new_tqe->tv = *tv;
|
new_tqe->ts = *ts;
|
||||||
new_tqe->class = SCH_ReservedTimeoutValue;
|
new_tqe->class = SCH_ReservedTimeoutValue;
|
||||||
|
|
||||||
/* Now work out where to insert the new entry in the list */
|
/* Now work out where to insert the new entry in the list */
|
||||||
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
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
|
/* If the new entry comes before the current pointer location in
|
||||||
the list, we want to insert the new entry just before ptr. */
|
the list, we want to insert the new entry just before ptr. */
|
||||||
break;
|
break;
|
||||||
|
@ -342,14 +342,14 @@ SCH_AddTimeout(struct timeval *tv, SCH_TimeoutHandler handler, SCH_ArbitraryArgu
|
||||||
SCH_TimeoutID
|
SCH_TimeoutID
|
||||||
SCH_AddTimeoutByDelay(double delay, SCH_TimeoutHandler handler, SCH_ArbitraryArgument arg)
|
SCH_AddTimeoutByDelay(double delay, SCH_TimeoutHandler handler, SCH_ArbitraryArgument arg)
|
||||||
{
|
{
|
||||||
struct timeval now, then;
|
struct timespec now, then;
|
||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
assert(delay >= 0.0);
|
assert(delay >= 0.0);
|
||||||
|
|
||||||
LCL_ReadRawTime(&now);
|
LCL_ReadRawTime(&now);
|
||||||
UTI_AddDoubleToTimeval(&now, delay, &then);
|
UTI_AddDoubleToTimespec(&now, delay, &then);
|
||||||
if (UTI_CompareTimevals(&now, &then) > 0) {
|
if (UTI_CompareTimespecs(&now, &then) > 0) {
|
||||||
LOG_FATAL(LOGF_Scheduler, "Timeout overflow");
|
LOG_FATAL(LOGF_Scheduler, "Timeout overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||||
{
|
{
|
||||||
TimerQueueEntry *new_tqe;
|
TimerQueueEntry *new_tqe;
|
||||||
TimerQueueEntry *ptr;
|
TimerQueueEntry *ptr;
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
double diff, r;
|
double diff, r;
|
||||||
double new_min_delay;
|
double new_min_delay;
|
||||||
|
|
||||||
|
@ -387,7 +387,7 @@ SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||||
new_min_delay = min_delay;
|
new_min_delay = min_delay;
|
||||||
|
|
||||||
/* Check the separation from the last dispatched timeout */
|
/* 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) {
|
if (diff < separation && diff >= 0.0 && diff + new_min_delay < separation) {
|
||||||
new_min_delay = separation - diff;
|
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 */
|
if necessary to keep at least the separation away */
|
||||||
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
for (ptr = timer_queue.next; ptr != &timer_queue; ptr = ptr->next) {
|
||||||
if (ptr->class == class) {
|
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) {
|
||||||
if (new_min_delay - diff < separation) {
|
if (new_min_delay - diff < separation) {
|
||||||
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) {
|
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) {
|
if (diff > new_min_delay) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,7 @@ SCH_AddTimeoutInClass(double min_delay, double separation, double randomness,
|
||||||
new_tqe->id = get_new_tqe_id();
|
new_tqe->id = get_new_tqe_id();
|
||||||
new_tqe->handler = handler;
|
new_tqe->handler = handler;
|
||||||
new_tqe->arg = arg;
|
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->class = class;
|
||||||
|
|
||||||
new_tqe->next = ptr;
|
new_tqe->next = ptr;
|
||||||
|
@ -476,7 +476,7 @@ SCH_RemoveTimeout(SCH_TimeoutID id)
|
||||||
completed). */
|
completed). */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dispatch_timeouts(struct timeval *now) {
|
dispatch_timeouts(struct timespec *now) {
|
||||||
TimerQueueEntry *ptr;
|
TimerQueueEntry *ptr;
|
||||||
SCH_TimeoutHandler handler;
|
SCH_TimeoutHandler handler;
|
||||||
SCH_ArbitraryArgument arg;
|
SCH_ArbitraryArgument arg;
|
||||||
|
@ -486,7 +486,7 @@ dispatch_timeouts(struct timeval *now) {
|
||||||
LCL_ReadRawTime(now);
|
LCL_ReadRawTime(now);
|
||||||
|
|
||||||
if (!(n_timer_queue_entries > 0 &&
|
if (!(n_timer_queue_entries > 0 &&
|
||||||
UTI_CompareTimevals(now, &(timer_queue.next->tv)) >= 0)) {
|
UTI_CompareTimespecs(now, &timer_queue.next->ts) >= 0)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,8 +547,8 @@ dispatch_filehandlers(int nfd, fd_set *read_fds, fd_set *write_fds)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
handle_slew(struct timeval *raw,
|
handle_slew(struct timespec *raw,
|
||||||
struct timeval *cooked,
|
struct timespec *cooked,
|
||||||
double dfreq,
|
double dfreq,
|
||||||
double doffset,
|
double doffset,
|
||||||
LCL_ChangeType change_type,
|
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 */
|
/* 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) {
|
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++) {
|
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
|
#define JUMP_DETECT_THRESHOLD 10
|
||||||
|
|
||||||
static int
|
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 *orig_select_tv,
|
||||||
struct timeval *rem_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;
|
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
|
/* 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
|
systems (e.g. Linux) the timeout timeval is modified to return the
|
||||||
remaining time, use that information. */
|
remaining time, use that information. */
|
||||||
if (timeout) {
|
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 &&
|
} 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_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)) {
|
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;
|
elapsed_max = elapsed_min;
|
||||||
} else {
|
} else {
|
||||||
if (rem_select_tv)
|
if (rem_select_tv)
|
||||||
elapsed_max = *orig_select_tv;
|
elapsed_max = orig_select_ts;
|
||||||
else
|
else
|
||||||
UTI_DiffTimevals(&elapsed_max, raw, prev_raw);
|
UTI_DiffTimespecs(&elapsed_max, raw, prev_raw);
|
||||||
elapsed_min.tv_sec = 0;
|
UTI_ZeroTimespec(&elapsed_min);
|
||||||
elapsed_min.tv_usec = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_select_ts_raw.tv_sec + elapsed_min.tv_sec >
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
UTI_DiffTimevalsToDouble(&step, &last_select_ts_raw, raw);
|
UTI_DiffTimespecsToDouble(&step, &last_select_ts_raw, raw);
|
||||||
UTI_TimevalToDouble(&elapsed_min, &elapsed);
|
UTI_TimespecToDouble(&elapsed_min, &elapsed);
|
||||||
step += elapsed;
|
step += elapsed;
|
||||||
|
|
||||||
/* Cooked time may no longer be valid after dispatching the handlers */
|
/* 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;
|
fd_set read_fds, write_fds, *p_read_fds, *p_write_fds;
|
||||||
int status, errsv;
|
int status, errsv;
|
||||||
struct timeval tv, saved_tv, *ptv;
|
struct timeval tv, saved_tv, *ptv;
|
||||||
struct timeval now, saved_now, cooked;
|
struct timespec ts, now, saved_now, cooked;
|
||||||
double err;
|
double err;
|
||||||
|
|
||||||
assert(initialised);
|
assert(initialised);
|
||||||
|
@ -697,12 +699,12 @@ SCH_MainLoop(void)
|
||||||
|
|
||||||
/* Check whether there is a timeout and set it up */
|
/* Check whether there is a timeout and set it up */
|
||||||
if (n_timer_queue_entries > 0) {
|
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;
|
ptv = &tv;
|
||||||
assert(tv.tv_sec > 0 || tv.tv_usec > 0);
|
|
||||||
saved_tv = tv;
|
saved_tv = tv;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ptv = NULL;
|
ptv = NULL;
|
||||||
/* This is needed to fix a compiler warning */
|
/* This is needed to fix a compiler warning */
|
||||||
|
|
4
sched.h
4
sched.h
|
@ -61,10 +61,10 @@ extern void SCH_RemoveFileHandler(int fd);
|
||||||
extern void SCH_SetFileHandlerEvents(int fd, int events);
|
extern void SCH_SetFileHandlerEvents(int fd, int events);
|
||||||
|
|
||||||
/* Get the time stamp taken after a file descriptor became ready or a timeout expired */
|
/* 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 */
|
/* 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 */
|
/* 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);
|
extern SCH_TimeoutID SCH_AddTimeoutByDelay(double delay, SCH_TimeoutHandler, SCH_ArbitraryArgument);
|
||||||
|
|
24
smooth.c
24
smooth.c
|
@ -93,17 +93,17 @@ static double max_freq;
|
||||||
/* Frequency offset, time offset and the time of the last smoothing update */
|
/* Frequency offset, time offset and the time of the last smoothing update */
|
||||||
static double smooth_freq;
|
static double smooth_freq;
|
||||||
static double smooth_offset;
|
static double smooth_offset;
|
||||||
static struct timeval last_update;
|
static struct timespec last_update;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_smoothing(struct timeval *now, double *poffset, double *pfreq,
|
get_smoothing(struct timespec *now, double *poffset, double *pfreq,
|
||||||
double *pwander)
|
double *pwander)
|
||||||
{
|
{
|
||||||
double elapsed, length, offset, freq, wander;
|
double elapsed, length, offset, freq, wander;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, now, &last_update);
|
UTI_DiffTimespecsToDouble(&elapsed, now, &last_update);
|
||||||
|
|
||||||
offset = smooth_offset;
|
offset = smooth_offset;
|
||||||
freq = smooth_freq;
|
freq = smooth_freq;
|
||||||
|
@ -195,7 +195,7 @@ update_stages(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static 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 */
|
/* Don't accept offset/frequency until the clock has stabilized */
|
||||||
if (locked) {
|
if (locked) {
|
||||||
|
@ -215,7 +215,7 @@ update_smoothing(struct timeval *now, double offset, double freq)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 doffset, LCL_ChangeType change_type, void *anything)
|
||||||
{
|
{
|
||||||
double delta;
|
double delta;
|
||||||
|
@ -227,7 +227,7 @@ handle_slew(struct timeval *raw, struct timeval *cooked, double dfreq,
|
||||||
update_smoothing(cooked, doffset, 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)
|
void SMT_Initialise(void)
|
||||||
|
@ -258,7 +258,7 @@ int SMT_IsEnabled(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
SMT_GetOffset(struct timeval *now)
|
SMT_GetOffset(struct timespec *now)
|
||||||
{
|
{
|
||||||
double offset, freq;
|
double offset, freq;
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ SMT_GetOffset(struct timeval *now)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SMT_Activate(struct timeval *now)
|
SMT_Activate(struct timespec *now)
|
||||||
{
|
{
|
||||||
if (!enabled || !locked)
|
if (!enabled || !locked)
|
||||||
return;
|
return;
|
||||||
|
@ -283,7 +283,7 @@ SMT_Activate(struct timeval *now)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SMT_Reset(struct timeval *now)
|
SMT_Reset(struct timespec *now)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ SMT_Reset(struct timeval *now)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
/* When the leap-only mode is disabled, the leap second will be accumulated
|
||||||
in handle_slew() as a normal offset */
|
in handle_slew() as a normal offset */
|
||||||
|
@ -310,7 +310,7 @@ SMT_Leap(struct timeval *now, int leap)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SMT_GetSmoothingReport(RPT_SmoothingReport *report, struct timeval *now)
|
SMT_GetSmoothingReport(RPT_SmoothingReport *report, struct timespec *now)
|
||||||
{
|
{
|
||||||
double length, elapsed;
|
double length, elapsed;
|
||||||
int i;
|
int i;
|
||||||
|
@ -327,7 +327,7 @@ SMT_GetSmoothingReport(RPT_SmoothingReport *report, struct timeval *now)
|
||||||
report->freq_ppm *= -1.0e6;
|
report->freq_ppm *= -1.0e6;
|
||||||
report->wander_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) {
|
if (!locked && elapsed >= 0.0) {
|
||||||
for (i = 0, length = 0.0; i < NUM_STAGES; i++)
|
for (i = 0, length = 0.0; i < NUM_STAGES; i++)
|
||||||
length += stages[i].length;
|
length += stages[i].length;
|
||||||
|
|
10
smooth.h
10
smooth.h
|
@ -35,14 +35,14 @@ extern void SMT_Finalise(void);
|
||||||
|
|
||||||
extern int SMT_IsEnabled(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
|
#endif
|
||||||
|
|
31
sources.c
31
sources.c
|
@ -166,7 +166,7 @@ static double combine_limit;
|
||||||
/* Forward prototype */
|
/* Forward prototype */
|
||||||
|
|
||||||
static void
|
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);
|
double doffset, LCL_ChangeType change_type, void *anything);
|
||||||
static void
|
static void
|
||||||
add_dispersion(double dispersion, void *anything);
|
add_dispersion(double dispersion, void *anything);
|
||||||
|
@ -341,7 +341,7 @@ void SRC_GetFrequencyRange(SRC_Instance instance, double *lo, double *hi)
|
||||||
|
|
||||||
void SRC_AccumulateSample
|
void SRC_AccumulateSample
|
||||||
(SRC_Instance inst,
|
(SRC_Instance inst,
|
||||||
struct timeval *sample_time,
|
struct timespec *sample_time,
|
||||||
double offset,
|
double offset,
|
||||||
double peer_delay,
|
double peer_delay,
|
||||||
double peer_dispersion,
|
double peer_dispersion,
|
||||||
|
@ -356,7 +356,8 @@ void SRC_AccumulateSample
|
||||||
inst->leap_status = leap_status;
|
inst->leap_status = leap_status;
|
||||||
|
|
||||||
DEBUG_LOG(LOGF_Sources, "ip=[%s] t=%s ofs=%f del=%f disp=%f str=%d",
|
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()) {
|
if (REF_IsLeapSecondClose()) {
|
||||||
LOG(LOGS_INFO, LOGF_Sources, "Dropping sample around leap second");
|
LOG(LOGS_INFO, LOGF_Sources, "Dropping sample around leap second");
|
||||||
|
@ -513,10 +514,10 @@ mark_ok_sources(SRC_Status status)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static int
|
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)
|
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_offset, src_offset_sd, src_frequency, src_skew;
|
||||||
double src_root_delay, src_root_dispersion, sel_src_distance, elapsed;
|
double src_root_delay, src_root_dispersion, sel_src_distance, elapsed;
|
||||||
double offset_weight, sum_offset_weight, sum_offset, sum2_offset_sd;
|
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)
|
if (sources[index]->status == SRC_OK)
|
||||||
sources[index]->status = SRC_UNSELECTED;
|
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;
|
src_offset += elapsed * src_frequency;
|
||||||
offset_weight = 1.0 / sources[index]->sel_info.root_distance;
|
offset_weight = 1.0 / sources[index]->sel_info.root_distance;
|
||||||
frequency_weight = 1.0 / src_skew;
|
frequency_weight = 1.0 / src_skew;
|
||||||
|
@ -603,7 +604,7 @@ void
|
||||||
SRC_SelectSource(SRC_Instance updated_inst)
|
SRC_SelectSource(SRC_Instance updated_inst)
|
||||||
{
|
{
|
||||||
struct SelectInfo *si;
|
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 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 n_badstats_sources, max_sel_reach, max_badstat_reach, sel_req_source;
|
||||||
int depth, best_depth, trust_depth, best_trust_depth;
|
int depth, best_depth, trust_depth, best_trust_depth;
|
||||||
|
@ -1097,7 +1098,7 @@ SRC_SetReselectDistance(double distance)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
double
|
double
|
||||||
SRC_PredictOffset(SRC_Instance inst, struct timeval *when)
|
SRC_PredictOffset(SRC_Instance inst, struct timespec *when)
|
||||||
{
|
{
|
||||||
return SST_PredictOffset(inst->stats, when);
|
return SST_PredictOffset(inst->stats, when);
|
||||||
}
|
}
|
||||||
|
@ -1114,7 +1115,7 @@ SRC_MinRoundTripDelay(SRC_Instance inst)
|
||||||
|
|
||||||
int
|
int
|
||||||
SRC_IsGoodSample(SRC_Instance inst, double offset, double delay,
|
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,
|
return SST_IsGoodSample(inst->stats, offset, delay, max_delay_dev_ratio,
|
||||||
clock_error, when);
|
clock_error, when);
|
||||||
|
@ -1128,12 +1129,8 @@ SRC_IsGoodSample(SRC_Instance inst, double offset, double delay,
|
||||||
the new regime. */
|
the new regime. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
slew_sources(struct timeval *raw,
|
slew_sources(struct timespec *raw, struct timespec *cooked, double dfreq,
|
||||||
struct timeval *cooked,
|
double doffset, LCL_ChangeType change_type, void *anything)
|
||||||
double dfreq,
|
|
||||||
double doffset,
|
|
||||||
LCL_ChangeType change_type,
|
|
||||||
void *anything)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -1286,7 +1283,7 @@ SRC_ActiveSources(void)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
|
SRC_ReportSource(int index, RPT_SourceReport *report, struct timespec *now)
|
||||||
{
|
{
|
||||||
SRC_Instance src;
|
SRC_Instance src;
|
||||||
if ((index >= n_sources) || (index < 0)) {
|
if ((index >= n_sources) || (index < 0)) {
|
||||||
|
@ -1341,7 +1338,7 @@ SRC_ReportSource(int index, RPT_SourceReport *report, struct timeval *now)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
int
|
int
|
||||||
SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timeval *now)
|
SRC_ReportSourcestats(int index, RPT_SourcestatsReport *report, struct timespec *now)
|
||||||
{
|
{
|
||||||
SRC_Instance src;
|
SRC_Instance src;
|
||||||
|
|
||||||
|
|
10
sources.h
10
sources.h
|
@ -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 */
|
/* This routine sets the source as receiving reachability updates */
|
||||||
extern void SRC_SetActive(SRC_Instance inst);
|
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
|
/* Predict the offset of the local clock relative to a given source at
|
||||||
a given local cooked time. Positive indicates local clock is FAST
|
a given local cooked time. Positive indicates local clock is FAST
|
||||||
relative to reference. */
|
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
|
/* Return the minimum peer delay amongst the previous samples
|
||||||
currently held in the register */
|
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
|
/* This routine determines if a new sample is good enough that it should be
|
||||||
accumulated */
|
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);
|
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_IsReachable(SRC_Instance inst);
|
||||||
extern int SRC_ReadNumberOfSources(void);
|
extern int SRC_ReadNumberOfSources(void);
|
||||||
extern int SRC_ActiveSources(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);
|
extern SRC_Type SRC_GetType(int index);
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ struct SST_Stats_Record {
|
||||||
/* This is the estimated offset (+ve => local fast) at a particular time */
|
/* This is the estimated offset (+ve => local fast) at a particular time */
|
||||||
double estimated_offset;
|
double estimated_offset;
|
||||||
double estimated_offset_sd;
|
double estimated_offset_sd;
|
||||||
struct timeval offset_time;
|
struct timespec offset_time;
|
||||||
|
|
||||||
/* Number of runs of the same sign amongst the residuals */
|
/* Number of runs of the same sign amongst the residuals */
|
||||||
int nruns;
|
int nruns;
|
||||||
|
@ -133,7 +133,7 @@ struct SST_Stats_Record {
|
||||||
|
|
||||||
/* This array contains the sample epochs, in terms of the local
|
/* This array contains the sample epochs, in terms of the local
|
||||||
clock. */
|
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
|
/* This is an array of offsets, in seconds, corresponding to the
|
||||||
sample times. In this module, we use the convention that
|
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->skew = 2000.0e-6;
|
||||||
inst->estimated_offset = 0.0;
|
inst->estimated_offset = 0.0;
|
||||||
inst->estimated_offset_sd = 86400.0; /* Assume it's at least within a day! */
|
inst->estimated_offset_sd = 86400.0; /* Assume it's at least within a day! */
|
||||||
inst->offset_time.tv_sec = 0;
|
UTI_ZeroTimespec(&inst->offset_time);
|
||||||
inst->offset_time.tv_usec = 0;
|
|
||||||
inst->variance = 16.0;
|
inst->variance = 16.0;
|
||||||
inst->nruns = 0;
|
inst->nruns = 0;
|
||||||
inst->asymmetry_run = 0;
|
inst->asymmetry_run = 0;
|
||||||
|
@ -275,7 +274,7 @@ prune_register(SST_Stats inst, int new_oldest)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
SST_AccumulateSample(SST_Stats inst, struct timeval *sample_time,
|
SST_AccumulateSample(SST_Stats inst, struct timespec *sample_time,
|
||||||
double offset,
|
double offset,
|
||||||
double peer_delay, double peer_dispersion,
|
double peer_delay, double peer_dispersion,
|
||||||
double root_delay, double root_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 */
|
/* Make sure it's newer than the last sample */
|
||||||
if (inst->n_samples &&
|
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",
|
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));
|
inst->ip_addr ? UTI_IPToString(inst->ip_addr) : UTI_RefidToString(inst->refid));
|
||||||
SST_ResetInstance(inst);
|
SST_ResetInstance(inst);
|
||||||
|
@ -345,14 +344,14 @@ get_buf_index(SST_Stats inst, int i)
|
||||||
static void
|
static void
|
||||||
convert_to_intervals(SST_Stats inst, double *times_back)
|
convert_to_intervals(SST_Stats inst, double *times_back)
|
||||||
{
|
{
|
||||||
struct timeval *newest_tv;
|
struct timespec *ts;
|
||||||
int i;
|
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++) {
|
for (i = -inst->runs_samples; i < inst->n_samples; i++) {
|
||||||
/* The entries in times_back[] should end up negative */
|
/* The entries in times_back[] should end up negative */
|
||||||
UTI_DiffTimevalsToDouble(×_back[i],
|
UTI_DiffTimespecsToDouble(×_back[i],
|
||||||
&inst->sample_times[get_runsbuf_index(inst, i)], newest_tv);
|
&inst->sample_times[get_runsbuf_index(inst, i)], ts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,7 +600,7 @@ SST_GetFrequencyRange(SST_Stats inst,
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
SST_GetSelectionData(SST_Stats inst, struct timeval *now,
|
SST_GetSelectionData(SST_Stats inst, struct timespec *now,
|
||||||
int *stratum,
|
int *stratum,
|
||||||
double *offset_lo_limit,
|
double *offset_lo_limit,
|
||||||
double *offset_hi_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)];
|
*stratum = inst->strata[get_buf_index(inst, inst->n_samples - 1)];
|
||||||
*variance = inst->variance;
|
*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;
|
offset = inst->offsets[i] + sample_elapsed * inst->estimated_frequency;
|
||||||
*root_distance = 0.5 * inst->root_delays[j] +
|
*root_distance = 0.5 * inst->root_delays[j] +
|
||||||
inst->root_dispersions[j] + sample_elapsed * inst->skew;
|
inst->root_dispersions[j] + sample_elapsed * inst->skew;
|
||||||
|
@ -637,7 +636,7 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
|
||||||
double average_offset, elapsed;
|
double average_offset, elapsed;
|
||||||
int average_ok;
|
int average_ok;
|
||||||
/* average_ok ignored for now */
|
/* 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;
|
average_offset = inst->estimated_offset + inst->estimated_frequency * elapsed;
|
||||||
if (fabs(average_offset - offset) <=
|
if (fabs(average_offset - offset) <=
|
||||||
inst->peer_dispersions[j] + 0.5 * inst->peer_delays[i]) {
|
inst->peer_dispersions[j] + 0.5 * inst->peer_delays[i]) {
|
||||||
|
@ -648,9 +647,9 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
i = get_runsbuf_index(inst, 0);
|
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);
|
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;
|
*select_ok = inst->regression_ok;
|
||||||
|
|
||||||
|
@ -662,7 +661,7 @@ SST_GetSelectionData(SST_Stats inst, struct timeval *now,
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
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 *average_offset, double *offset_sd,
|
||||||
double *frequency, double *skew,
|
double *frequency, double *skew,
|
||||||
double *root_delay, double *root_dispersion)
|
double *root_delay, double *root_dispersion)
|
||||||
|
@ -682,7 +681,7 @@ SST_GetTrackingData(SST_Stats inst, struct timeval *ref_time,
|
||||||
*skew = inst->skew;
|
*skew = inst->skew;
|
||||||
*root_delay = inst->root_delays[j];
|
*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;
|
*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",
|
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
|
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;
|
int m, i;
|
||||||
double delta_time;
|
double delta_time;
|
||||||
struct timeval *sample, prev;
|
struct timespec *sample, prev;
|
||||||
double prev_offset, prev_freq;
|
double prev_offset, prev_freq;
|
||||||
|
|
||||||
if (!inst->n_samples)
|
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++) {
|
for (m = -inst->runs_samples; m < inst->n_samples; m++) {
|
||||||
i = get_runsbuf_index(inst, m);
|
i = get_runsbuf_index(inst, m);
|
||||||
sample = &(inst->sample_times[i]);
|
sample = &inst->sample_times[i];
|
||||||
prev = *sample;
|
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;
|
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 = inst->offset_time;
|
||||||
prev_offset = inst->estimated_offset;
|
prev_offset = inst->estimated_offset;
|
||||||
prev_freq = inst->estimated_frequency;
|
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);
|
&delta_time, dfreq, doffset);
|
||||||
inst->estimated_offset += delta_time;
|
inst->estimated_offset += delta_time;
|
||||||
inst->estimated_frequency = (inst->estimated_frequency - dfreq) / (1.0 - dfreq);
|
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",
|
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,
|
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,
|
prev_offset, inst->estimated_offset,
|
||||||
1.0e6 * prev_freq, 1.0e6 * inst->estimated_frequency);
|
1.0e6 * prev_freq, 1.0e6 * inst->estimated_frequency);
|
||||||
}
|
}
|
||||||
|
@ -744,7 +743,7 @@ SST_AddDispersion(SST_Stats inst, double dispersion)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
double
|
double
|
||||||
SST_PredictOffset(SST_Stats inst, struct timeval *when)
|
SST_PredictOffset(SST_Stats inst, struct timespec *when)
|
||||||
{
|
{
|
||||||
double elapsed;
|
double elapsed;
|
||||||
|
|
||||||
|
@ -758,7 +757,7 @@ SST_PredictOffset(SST_Stats inst, struct timeval *when)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, when, &inst->offset_time);
|
UTI_DiffTimespecsToDouble(&elapsed, when, &inst->offset_time);
|
||||||
return inst->estimated_offset + elapsed * inst->estimated_frequency;
|
return inst->estimated_offset + elapsed * inst->estimated_frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,14 +777,14 @@ SST_MinRoundTripDelay(SST_Stats inst)
|
||||||
|
|
||||||
int
|
int
|
||||||
SST_IsGoodSample(SST_Stats inst, double offset, double delay,
|
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;
|
double elapsed, allowed_increase, delay_increase;
|
||||||
|
|
||||||
if (inst->n_samples < 3)
|
if (inst->n_samples < 3)
|
||||||
return 1;
|
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
|
/* 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
|
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",
|
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_sec,
|
||||||
(unsigned long) inst->sample_times[i].tv_usec,
|
(unsigned long)inst->sample_times[i].tv_nsec / 1000,
|
||||||
inst->offsets[i],
|
inst->offsets[i],
|
||||||
inst->orig_offsets[j],
|
inst->orig_offsets[j],
|
||||||
inst->peer_delays[i],
|
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 */
|
/* This is the branch taken if the read is SUCCESSFUL */
|
||||||
inst->sample_times[i].tv_sec = sec;
|
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++;
|
line_number++;
|
||||||
}
|
}
|
||||||
|
@ -906,10 +906,10 @@ SST_LoadFromFile(SST_Stats inst, FILE *in)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
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;
|
int i, j;
|
||||||
struct timeval ago;
|
struct timespec ago;
|
||||||
|
|
||||||
if (inst->n_samples > 0) {
|
if (inst->n_samples > 0) {
|
||||||
i = get_runsbuf_index(inst, inst->n_samples - 1);
|
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->latest_meas_err = 0.5*inst->root_delays[j] + inst->root_dispersions[j];
|
||||||
report->stratum = inst->strata[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;
|
report->latest_meas_ago = ago.tv_sec;
|
||||||
} else {
|
} else {
|
||||||
report->latest_meas_ago = (uint32_t)-1;
|
report->latest_meas_ago = (uint32_t)-1;
|
||||||
|
@ -941,7 +941,7 @@ SST_Samples(SST_Stats inst)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
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 dspan;
|
||||||
double elapsed, sample_elapsed;
|
double elapsed, sample_elapsed;
|
||||||
|
@ -953,15 +953,15 @@ SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report, struct ti
|
||||||
if (inst->n_samples > 1) {
|
if (inst->n_samples > 1) {
|
||||||
li = get_runsbuf_index(inst, inst->n_samples - 1);
|
li = get_runsbuf_index(inst, inst->n_samples - 1);
|
||||||
lj = get_buf_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)]);
|
&inst->sample_times[get_runsbuf_index(inst, 0)]);
|
||||||
report->span_seconds = (unsigned long) (dspan + 0.5);
|
report->span_seconds = (unsigned long) (dspan + 0.5);
|
||||||
|
|
||||||
if (inst->n_samples > 3) {
|
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);
|
bi = get_runsbuf_index(inst, inst->best_single_sample);
|
||||||
bj = get_buf_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 = inst->estimated_offset + elapsed * inst->estimated_frequency;
|
||||||
report->est_offset_err = (inst->estimated_offset_sd +
|
report->est_offset_err = (inst->estimated_offset_sd +
|
||||||
sample_elapsed * inst->skew +
|
sample_elapsed * inst->skew +
|
||||||
|
|
|
@ -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.
|
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
|
/* This function runs the linear regression operation on the data. It
|
||||||
finds the set of most recent samples that give the tightest
|
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 */
|
/* Get data needed for selection */
|
||||||
extern void
|
extern void
|
||||||
SST_GetSelectionData(SST_Stats inst, struct timeval *now,
|
SST_GetSelectionData(SST_Stats inst, struct timespec *now,
|
||||||
int *stratum,
|
int *stratum,
|
||||||
double *offset_lo_limit,
|
double *offset_lo_limit,
|
||||||
double *offset_hi_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 */
|
/* Get data needed when setting up tracking on this source */
|
||||||
extern void
|
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 *average_offset, double *offset_sd,
|
||||||
double *frequency, double *skew,
|
double *frequency, double *skew,
|
||||||
double *root_delay, double *root_dispersion);
|
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
|
/* This routine is called when an indeterminate offset is introduced
|
||||||
into the local time. */
|
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
|
/* Predict the offset of the local clock relative to a given source at
|
||||||
a given local cooked time. Positive indicates local clock is FAST
|
a given local cooked time. Positive indicates local clock is FAST
|
||||||
relative to reference. */
|
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 */
|
/* Find the minimum round trip delay in the register */
|
||||||
extern double SST_MinRoundTripDelay(SST_Stats inst);
|
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
|
/* This routine determines if a new sample is good enough that it should be
|
||||||
accumulated */
|
accumulated */
|
||||||
extern int SST_IsGoodSample(SST_Stats inst, double offset, double delay,
|
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 void SST_SaveToFile(SST_Stats inst, FILE *out);
|
||||||
|
|
||||||
extern int SST_LoadFromFile(SST_Stats inst, FILE *in);
|
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);
|
extern int SST_Samples(SST_Stats inst);
|
||||||
|
|
||||||
|
|
4
stubs.c
4
stubs.c
|
@ -292,7 +292,7 @@ NSR_ModifyPolltarget(IPAddr *address, int new_poll_target)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NSR_ReportSource(RPT_SourceReport *report, struct timeval *now)
|
NSR_ReportSource(RPT_SourceReport *report, struct timespec *now)
|
||||||
{
|
{
|
||||||
memset(report, 0, sizeof (*report));
|
memset(report, 0, sizeof (*report));
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ RCL_StartRefclocks(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RCL_ReportSource(RPT_SourceReport *report, struct timeval *now)
|
RCL_ReportSource(RPT_SourceReport *report, struct timespec *now)
|
||||||
{
|
{
|
||||||
memset(report, 0, sizeof (*report));
|
memset(report, 0, sizeof (*report));
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ static double offset_register;
|
||||||
static double slew_freq;
|
static double slew_freq;
|
||||||
|
|
||||||
/* Time (raw) of last update of slewing frequency and offset */
|
/* 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 */
|
/* Limits for the slew timeout */
|
||||||
#define MIN_SLEW_TIMEOUT 1.0
|
#define MIN_SLEW_TIMEOUT 1.0
|
||||||
|
@ -106,7 +106,7 @@ static void update_slew(void);
|
||||||
/* Adjust slew_start on clock step */
|
/* Adjust slew_start on clock step */
|
||||||
|
|
||||||
static void
|
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)
|
double doffset, LCL_ChangeType change_type, void *anything)
|
||||||
{
|
{
|
||||||
if (change_type == LCL_ChangeUnknownStep) {
|
if (change_type == LCL_ChangeUnknownStep) {
|
||||||
|
@ -115,7 +115,7 @@ handle_step(struct timeval *raw, struct timeval *cooked, double dfreq,
|
||||||
offset_register = 0.0;
|
offset_register = 0.0;
|
||||||
update_slew();
|
update_slew();
|
||||||
} else if (change_type == LCL_ChangeStep) {
|
} 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
|
static void
|
||||||
stop_fastslew(struct timeval *now)
|
stop_fastslew(struct timespec *now)
|
||||||
{
|
{
|
||||||
double corr;
|
double corr;
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ clamp_freq(double freq)
|
||||||
static void
|
static void
|
||||||
update_slew(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;
|
double old_slew_freq, total_freq, corr_freq, duration;
|
||||||
|
|
||||||
/* Remove currently running timeout */
|
/* Remove currently running timeout */
|
||||||
|
@ -178,7 +178,7 @@ update_slew(void)
|
||||||
LCL_ReadRawTime(&now);
|
LCL_ReadRawTime(&now);
|
||||||
|
|
||||||
/* Adjust the offset register by achieved slew */
|
/* Adjust the offset register by achieved slew */
|
||||||
UTI_DiffTimevalsToDouble(&duration, &now, &slew_start);
|
UTI_DiffTimespecsToDouble(&duration, &now, &slew_start);
|
||||||
offset_register -= slew_freq * duration;
|
offset_register -= slew_freq * duration;
|
||||||
|
|
||||||
stop_fastslew(&now);
|
stop_fastslew(&now);
|
||||||
|
@ -242,7 +242,7 @@ update_slew(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restart timer for the next update */
|
/* 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_timeout_id = SCH_AddTimeout(&end_of_slew, handle_end_of_slew, NULL);
|
||||||
slew_start = now;
|
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 */
|
/* Determine the correction to generate the cooked time for given raw time */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
offset_convert(struct timeval *raw,
|
offset_convert(struct timespec *raw,
|
||||||
double *corr, double *err)
|
double *corr, double *err)
|
||||||
{
|
{
|
||||||
double duration, fastslew_corr, fastslew_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) {
|
if (drv_get_offset_correction && fastslew_active) {
|
||||||
drv_get_offset_correction(raw, &fastslew_corr, &fastslew_err);
|
drv_get_offset_correction(raw, &fastslew_corr, &fastslew_err);
|
||||||
|
@ -324,19 +324,21 @@ offset_convert(struct timeval *raw,
|
||||||
static int
|
static int
|
||||||
apply_step_offset(double offset)
|
apply_step_offset(double offset)
|
||||||
{
|
{
|
||||||
struct timeval old_time, new_time;
|
struct timespec old_time, new_time;
|
||||||
|
struct timeval new_time_tv;
|
||||||
double err;
|
double err;
|
||||||
|
|
||||||
LCL_ReadRawTime(&old_time);
|
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");
|
DEBUG_LOG(LOGF_SysGeneric, "settimeofday() failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LCL_ReadRawTime(&old_time);
|
LCL_ReadRawTime(&old_time);
|
||||||
UTI_DiffTimevalsToDouble(&err, &old_time, &new_time);
|
UTI_DiffTimespecsToDouble(&err, &old_time, &new_time);
|
||||||
|
|
||||||
lcl_InvokeDispersionNotifyHandlers(fabs(err));
|
lcl_InvokeDispersionNotifyHandlers(fabs(err));
|
||||||
|
|
||||||
|
@ -403,7 +405,7 @@ SYS_Generic_CompleteFreqDriver(double max_set_freq_ppm, double max_set_freq_dela
|
||||||
void
|
void
|
||||||
SYS_Generic_Finalise(void)
|
SYS_Generic_Finalise(void)
|
||||||
{
|
{
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
|
|
||||||
/* Must *NOT* leave a slew running - clock could drift way off
|
/* Must *NOT* leave a slew running - clock could drift way off
|
||||||
if the daemon is not restarted */
|
if the daemon is not restarted */
|
||||||
|
|
55
sys_macosx.c
55
sys_macosx.c
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include "sys_macosx.h"
|
#include "sys_macosx.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "local.h"
|
||||||
#include "localp.h"
|
#include "localp.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
|
@ -49,13 +50,13 @@
|
||||||
|
|
||||||
/* This register contains the number of seconds by which the local
|
/* This register contains the number of seconds by which the local
|
||||||
clock was estimated to be fast of reference time at the epoch when
|
clock was estimated to be fast of reference time at the epoch when
|
||||||
gettimeofday() returned T0 */
|
LCL_ReadRawTime() returned T0 */
|
||||||
|
|
||||||
static double offset_register;
|
static double offset_register;
|
||||||
|
|
||||||
/* This register contains the epoch to which the offset is referenced */
|
/* 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
|
/* This register contains the current estimate of the system
|
||||||
frequency, in absolute (NOT ppm) */
|
frequency, in absolute (NOT ppm) */
|
||||||
|
@ -79,7 +80,7 @@ static double adjustment_requested;
|
||||||
|
|
||||||
static double drift_removal_interval;
|
static double drift_removal_interval;
|
||||||
static double current_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 */
|
/* weighting applied to error in calculating drift_removal_interval */
|
||||||
#define ERROR_WEIGHT (0.5)
|
#define ERROR_WEIGHT (0.5)
|
||||||
|
@ -91,7 +92,7 @@ static struct timeval Tdrift;
|
||||||
|
|
||||||
/* RTC synchronisation - once an hour */
|
/* RTC synchronisation - once an hour */
|
||||||
|
|
||||||
static struct timeval last_rtc_sync;
|
static struct timespec last_rtc_sync;
|
||||||
#define RTC_SYNC_INTERVAL (60 * 60.0)
|
#define RTC_SYNC_INTERVAL (60 * 60.0)
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
@ -107,9 +108,7 @@ clock_initialise(void)
|
||||||
drift_removal_interval = DRIFT_REMOVAL_INTERVAL;
|
drift_removal_interval = DRIFT_REMOVAL_INTERVAL;
|
||||||
current_drift_removal_interval = DRIFT_REMOVAL_INTERVAL;
|
current_drift_removal_interval = DRIFT_REMOVAL_INTERVAL;
|
||||||
|
|
||||||
if (gettimeofday(&T0, NULL) < 0) {
|
LCL_ReadRawTime(&T0);
|
||||||
LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
|
|
||||||
}
|
|
||||||
Tdrift = T0;
|
Tdrift = T0;
|
||||||
last_rtc_sync = T0;
|
last_rtc_sync = T0;
|
||||||
|
|
||||||
|
@ -135,21 +134,19 @@ static void
|
||||||
start_adjust(void)
|
start_adjust(void)
|
||||||
{
|
{
|
||||||
struct timeval newadj, oldadj;
|
struct timeval newadj, oldadj;
|
||||||
struct timeval T1;
|
struct timespec T1;
|
||||||
double elapsed, accrued_error, predicted_error, drift_removal_elapsed;
|
double elapsed, accrued_error, predicted_error, drift_removal_elapsed;
|
||||||
double adjust_required;
|
double adjust_required;
|
||||||
double rounding_error;
|
double rounding_error;
|
||||||
double old_adjust_remaining;
|
double old_adjust_remaining;
|
||||||
|
|
||||||
/* Determine the amount of error built up since the last adjustment */
|
/* Determine the amount of error built up since the last adjustment */
|
||||||
if (gettimeofday(&T1, NULL) < 0) {
|
LCL_ReadRawTime(&T1);
|
||||||
LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
|
UTI_DiffTimespecsToDouble(&elapsed, &T1, &T0);
|
||||||
accrued_error = elapsed * current_freq;
|
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
|
/* To allow for the clock being stepped either forward or backwards, clamp
|
||||||
the elapsed time to bounds [ 0.0, current_drift_removal_interval ] */
|
the elapsed time to bounds [ 0.0, current_drift_removal_interval ] */
|
||||||
|
@ -184,7 +181,7 @@ start_adjust(void)
|
||||||
static void
|
static void
|
||||||
stop_adjust(void)
|
stop_adjust(void)
|
||||||
{
|
{
|
||||||
struct timeval T1;
|
struct timespec T1;
|
||||||
struct timeval zeroadj, remadj;
|
struct timeval zeroadj, remadj;
|
||||||
double adjustment_remaining, adjustment_achieved;
|
double adjustment_remaining, adjustment_achieved;
|
||||||
double elapsed, elapsed_plus_adjust;
|
double elapsed, elapsed_plus_adjust;
|
||||||
|
@ -196,11 +193,9 @@ stop_adjust(void)
|
||||||
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
|
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gettimeofday(&T1, NULL) < 0) {
|
LCL_ReadRawTime(&T1);
|
||||||
LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, &T1, &T0);
|
UTI_DiffTimespecsToDouble(&elapsed, &T1, &T0);
|
||||||
UTI_TimevalToDouble(&remadj, &adjustment_remaining);
|
UTI_TimevalToDouble(&remadj, &adjustment_remaining);
|
||||||
|
|
||||||
adjustment_achieved = adjustment_requested - adjustment_remaining;
|
adjustment_achieved = adjustment_requested - adjustment_remaining;
|
||||||
|
@ -233,22 +228,22 @@ accrue_offset(double offset, double corr_rate)
|
||||||
static int
|
static int
|
||||||
apply_step_offset(double offset)
|
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();
|
stop_adjust();
|
||||||
|
|
||||||
if (gettimeofday(&old_time, NULL) < 0) {
|
LCL_ReadRawTime(&old_time);
|
||||||
LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
DEBUG_LOG(LOGF_SysMacOSX, "settimeofday() failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UTI_AddDoubleToTimeval(&T0, -offset, &T1);
|
UTI_AddDoubleToTimespec(&T0, -offset, &T1);
|
||||||
T0 = T1;
|
T0 = T1;
|
||||||
|
|
||||||
start_adjust();
|
start_adjust();
|
||||||
|
@ -279,7 +274,7 @@ read_frequency(void)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_offset_correction(struct timeval *raw,
|
get_offset_correction(struct timespec *raw,
|
||||||
double *corr, double *err)
|
double *corr, double *err)
|
||||||
{
|
{
|
||||||
stop_adjust();
|
stop_adjust();
|
||||||
|
@ -311,9 +306,7 @@ drift_removal_timeout(SCH_ArbitraryArgument not_used)
|
||||||
|
|
||||||
stop_adjust();
|
stop_adjust();
|
||||||
|
|
||||||
if (gettimeofday(&Tdrift, NULL) < 0) {
|
LCL_ReadRawTime(&Tdrift);
|
||||||
LOG_FATAL(LOGF_SysMacOSX, "gettimeofday() failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
current_drift_removal_interval = drift_removal_interval;
|
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);
|
drift_removal_interval = MAX(drift_removal_interval, DRIFT_REMOVAL_INTERVAL);
|
||||||
} else {
|
} else {
|
||||||
if (CNF_GetRtcSync()) {
|
if (CNF_GetRtcSync()) {
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
double rtc_sync_elapsed;
|
double rtc_sync_elapsed;
|
||||||
|
|
||||||
SCH_GetLastEventTime(NULL, NULL, &now);
|
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) {
|
if (fabs(rtc_sync_elapsed) >= RTC_SYNC_INTERVAL) {
|
||||||
/* update the RTC by applying a step of 0.0 secs */
|
/* update the RTC by applying a step of 0.0 secs */
|
||||||
apply_step_offset(0.0);
|
apply_step_offset(0.0);
|
||||||
|
|
|
@ -60,6 +60,7 @@ static void
|
||||||
accrue_offset(double offset, double corr_rate)
|
accrue_offset(double offset, double corr_rate)
|
||||||
{
|
{
|
||||||
struct timeval newadj, oldadj;
|
struct timeval newadj, oldadj;
|
||||||
|
double doldadj;
|
||||||
|
|
||||||
UTI_DoubleToTimeval(-offset, &newadj);
|
UTI_DoubleToTimeval(-offset, &newadj);
|
||||||
|
|
||||||
|
@ -67,9 +68,9 @@ accrue_offset(double offset, double corr_rate)
|
||||||
LOG_FATAL(LOGF_SysNetBSD, "adjtime() failed");
|
LOG_FATAL(LOGF_SysNetBSD, "adjtime() failed");
|
||||||
|
|
||||||
/* Add the old remaining adjustment if not zero */
|
/* Add the old remaining adjustment if not zero */
|
||||||
UTI_TimevalToDouble(&oldadj, &offset);
|
UTI_TimevalToDouble(&oldadj, &doldadj);
|
||||||
if (offset != 0.0) {
|
if (doldadj != 0.0) {
|
||||||
UTI_AddDoubleToTimeval(&newadj, offset, &newadj);
|
UTI_DoubleToTimeval(-offset + doldadj, &newadj);
|
||||||
if (PRV_AdjustTime(&newadj, NULL) < 0)
|
if (PRV_AdjustTime(&newadj, NULL) < 0)
|
||||||
LOG_FATAL(LOGF_SysNetBSD, "adjtime() failed");
|
LOG_FATAL(LOGF_SysNetBSD, "adjtime() failed");
|
||||||
}
|
}
|
||||||
|
@ -78,7 +79,7 @@ accrue_offset(double offset, double corr_rate)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_offset_correction(struct timeval *raw,
|
get_offset_correction(struct timespec *raw,
|
||||||
double *corr, double *err)
|
double *corr, double *err)
|
||||||
{
|
{
|
||||||
struct timeval remadj;
|
struct timeval remadj;
|
||||||
|
|
|
@ -95,7 +95,7 @@ read_timeout(void *arg)
|
||||||
DEBUG_LOG(LOGF_TempComp, "tempcomp updated to %f for %f", comp, temp);
|
DEBUG_LOG(LOGF_TempComp, "tempcomp updated to %f for %f", comp, temp);
|
||||||
|
|
||||||
if (logfileid != -1) {
|
if (logfileid != -1) {
|
||||||
struct timeval now;
|
struct timespec now;
|
||||||
|
|
||||||
LCL_ReadCookedTime(&now, NULL);
|
LCL_ReadCookedTime(&now, NULL);
|
||||||
LOG_FileWrite(logfileid, "%s %11.4e %11.4e",
|
LOG_FileWrite(logfileid, "%s %11.4e %11.4e",
|
||||||
|
|
|
@ -25,7 +25,7 @@ void
|
||||||
test_unit(void)
|
test_unit(void)
|
||||||
{
|
{
|
||||||
int i, j, index;
|
int i, j, index;
|
||||||
struct timeval tv;
|
struct timespec ts;
|
||||||
IPAddr ip;
|
IPAddr ip;
|
||||||
char conf[][100] = {
|
char conf[][100] = {
|
||||||
"clientloglimit 10000",
|
"clientloglimit 10000",
|
||||||
|
@ -44,24 +44,24 @@ test_unit(void)
|
||||||
for (i = 0; i < 500; i++) {
|
for (i = 0; i < 500; i++) {
|
||||||
DEBUG_LOG(0, "iteration %d", i);
|
DEBUG_LOG(0, "iteration %d", i);
|
||||||
|
|
||||||
tv.tv_sec = (time_t)random() & 0x0fffffff;
|
ts.tv_sec = (time_t)random() & 0x0fffffff;
|
||||||
tv.tv_usec = 0;
|
ts.tv_nsec = 0;
|
||||||
|
|
||||||
for (j = 0; j < 1000; j++) {
|
for (j = 0; j < 1000; j++) {
|
||||||
TST_GetRandomAddress(&ip, IPADDR_UNSPEC, i % 8 ? -1 : i / 8 % 9);
|
TST_GetRandomAddress(&ip, IPADDR_UNSPEC, i % 8 ? -1 : i / 8 % 9);
|
||||||
DEBUG_LOG(0, "address %s", UTI_IPToString(&ip));
|
DEBUG_LOG(0, "address %s", UTI_IPToString(&ip));
|
||||||
|
|
||||||
if (random() % 2) {
|
if (random() % 2) {
|
||||||
index = CLG_LogNTPAccess(&ip, &tv);
|
index = CLG_LogNTPAccess(&ip, &ts);
|
||||||
TEST_CHECK(index >= 0);
|
TEST_CHECK(index >= 0);
|
||||||
CLG_LimitNTPResponseRate(index);
|
CLG_LimitNTPResponseRate(index);
|
||||||
} else {
|
} else {
|
||||||
index = CLG_LogCommandAccess(&ip, &tv);
|
index = CLG_LogCommandAccess(&ip, &ts);
|
||||||
TEST_CHECK(index >= 0);
|
TEST_CHECK(index >= 0);
|
||||||
CLG_LimitCommandResponseRate(index);
|
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);
|
TEST_CHECK(ARR_GetSize(records) == 128);
|
||||||
|
|
||||||
for (i = j = 0; i < 10000; i++) {
|
for (i = j = 0; i < 10000; i++) {
|
||||||
tv.tv_sec += 1;
|
ts.tv_sec += 1;
|
||||||
index = CLG_LogNTPAccess(&ip, &tv);
|
index = CLG_LogNTPAccess(&ip, &ts);
|
||||||
TEST_CHECK(index >= 0);
|
TEST_CHECK(index >= 0);
|
||||||
if (!CLG_LimitNTPResponseRate(index))
|
if (!CLG_LimitNTPResponseRate(index))
|
||||||
j++;
|
j++;
|
||||||
|
|
|
@ -29,7 +29,7 @@ test_unit(void)
|
||||||
IPAddr addr;
|
IPAddr addr;
|
||||||
int i, j, k, l, samples, sel_options;
|
int i, j, k, l, samples, sel_options;
|
||||||
double offset, delay, disp;
|
double offset, delay, disp;
|
||||||
struct timeval tv;
|
struct timespec ts;
|
||||||
|
|
||||||
CNF_Initialise(0);
|
CNF_Initialise(0);
|
||||||
LCL_Initialise();
|
LCL_Initialise();
|
||||||
|
@ -61,8 +61,8 @@ test_unit(void)
|
||||||
offset = TST_GetRandomDouble(-1.0, 1.0);
|
offset = TST_GetRandomDouble(-1.0, 1.0);
|
||||||
|
|
||||||
for (k = 0; k < samples; k++) {
|
for (k = 0; k < samples; k++) {
|
||||||
SCH_GetLastEventTime(&tv, NULL, NULL);
|
SCH_GetLastEventTime(&ts, NULL, NULL);
|
||||||
UTI_AddDoubleToTimeval(&tv, TST_GetRandomDouble(k - samples, k - samples + 1), &tv);
|
UTI_AddDoubleToTimespec(&ts, TST_GetRandomDouble(k - samples, k - samples + 1), &ts);
|
||||||
|
|
||||||
offset += TST_GetRandomDouble(-1.0e-2, 1.0e-2);
|
offset += TST_GetRandomDouble(-1.0e-2, 1.0e-2);
|
||||||
delay = TST_GetRandomDouble(1.0e-6, 1.0e-1);
|
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,
|
DEBUG_LOG(0, "source %d sample %d offset %f delay %f disp %f", j, k,
|
||||||
offset, delay, disp);
|
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);
|
1, LEAP_Normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ test_unit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < sizeof (srcs) / sizeof (srcs[0]); j++) {
|
for (j = 0; j < sizeof (srcs) / sizeof (srcs[0]); j++) {
|
||||||
SRC_ReportSource(j, &report, &tv);
|
SRC_ReportSource(j, &report, &ts);
|
||||||
SRC_DestroyInstance(srcs[j]);
|
SRC_DestroyInstance(srcs[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,7 @@ apply_step_offset(double offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
offset_convert(struct timeval *raw, double *corr, double *err)
|
offset_convert(struct timespec *raw, double *corr, double *err)
|
||||||
{
|
{
|
||||||
*corr = 0.0;
|
*corr = 0.0;
|
||||||
if (err)
|
if (err)
|
||||||
|
|
250
util.c
250
util.c
|
@ -34,6 +34,70 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "hash.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
|
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
|
void
|
||||||
UTI_NormaliseTimeval(struct timeval *x)
|
UTI_NormaliseTimeval(struct timeval *x)
|
||||||
{
|
{
|
||||||
|
@ -99,100 +143,73 @@ UTI_NormaliseTimeval(struct timeval *x)
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
int
|
||||||
|
UTI_CompareTimespecs(struct timespec *a, struct timespec *b)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
UTI_DiffTimevals(struct timeval *result,
|
UTI_DiffTimespecs(struct timespec *result, struct timespec *a, struct timespec *b)
|
||||||
struct timeval *a,
|
|
||||||
struct timeval *b)
|
|
||||||
{
|
{
|
||||||
result->tv_sec = a->tv_sec - b->tv_sec;
|
result->tv_sec = a->tv_sec - b->tv_sec;
|
||||||
result->tv_usec = a->tv_usec - b->tv_usec;
|
result->tv_nsec = a->tv_nsec - b->tv_nsec;
|
||||||
|
UTI_NormaliseTimespec(result);
|
||||||
/* Correct microseconds field to bring it into the range
|
|
||||||
(0,1000000) */
|
|
||||||
|
|
||||||
UTI_NormaliseTimeval(result); /* JGH */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
/* Calculate result = a - b and return as a double */
|
/* Calculate result = a - b and return as a double */
|
||||||
void
|
void
|
||||||
UTI_DiffTimevalsToDouble(double *result,
|
UTI_DiffTimespecsToDouble(double *result, struct timespec *a, struct timespec *b)
|
||||||
struct timeval *a,
|
|
||||||
struct timeval *b)
|
|
||||||
{
|
{
|
||||||
*result = (double)(a->tv_sec - b->tv_sec) +
|
*result = (a->tv_sec - b->tv_sec) + 1.0e-9 * (a->tv_nsec - b->tv_nsec);
|
||||||
(double)(a->tv_usec - b->tv_usec) * 1.0e-6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
UTI_AddDoubleToTimeval(struct timeval *start,
|
UTI_AddDoubleToTimespec(struct timespec *start, double increment, struct timespec *end)
|
||||||
double increment,
|
|
||||||
struct timeval *end)
|
|
||||||
{
|
{
|
||||||
long int_part, frac_part;
|
time_t int_part;
|
||||||
|
|
||||||
/* Don't want to do this by using (long)(1000000 * increment), since
|
int_part = increment;
|
||||||
that will only cope with increments up to +/- 2148 seconds, which
|
end->tv_sec = start->tv_sec + int_part;
|
||||||
is too marginal here. */
|
end->tv_nsec = start->tv_nsec + 1.0e9 * (increment - int_part);
|
||||||
|
UTI_NormaliseTimespec(end);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
/* Calculate the average and difference (as a double) of two timevals */
|
/* Calculate the average and difference (as a double) of two timespecs */
|
||||||
void
|
void
|
||||||
UTI_AverageDiffTimevals (struct timeval *earlier,
|
UTI_AverageDiffTimespecs(struct timespec *earlier, struct timespec *later,
|
||||||
struct timeval *later,
|
struct timespec *average, double *diff)
|
||||||
struct timeval *average,
|
|
||||||
double *diff)
|
|
||||||
{
|
{
|
||||||
struct timeval tvdiff;
|
UTI_DiffTimespecsToDouble(diff, later, earlier);
|
||||||
struct timeval tvhalf;
|
UTI_AddDoubleToTimespec(earlier, *diff / 2.0, average);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
UTI_AddDiffToTimeval(struct timeval *a, struct timeval *b,
|
UTI_AddDiffToTimespec(struct timespec *a, struct timespec *b,
|
||||||
struct timeval *c, struct timeval *result)
|
struct timespec *c, struct timespec *result)
|
||||||
{
|
{
|
||||||
double diff;
|
double diff;
|
||||||
|
|
||||||
UTI_DiffTimevalsToDouble(&diff, a, b);
|
UTI_DiffTimespecsToDouble(&diff, a, b);
|
||||||
UTI_AddDoubleToTimeval(c, diff, result);
|
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)])
|
#define NEXT_BUFFER (buffer_pool[pool_ptr = ((pool_ptr + 1) % POOL_ENTRIES)])
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Convert a timeval into a temporary string, largely for diagnostic
|
/* Convert a timespec into a temporary string, largely for diagnostic display */
|
||||||
display */
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
UTI_TimevalToString(struct timeval *tv)
|
UTI_TimespecToString(struct timespec *ts)
|
||||||
{
|
{
|
||||||
char *result;
|
char *result;
|
||||||
|
|
||||||
result = NEXT_BUFFER;
|
result = NEXT_BUFFER;
|
||||||
#ifdef HAVE_LONG_TIME_T
|
#ifdef HAVE_LONG_TIME_T
|
||||||
snprintf(result, BUFFER_LENGTH, "%"PRId64".%06lu",
|
snprintf(result, BUFFER_LENGTH, "%"PRId64".%09lu",
|
||||||
(int64_t)tv->tv_sec, (unsigned long)tv->tv_usec);
|
(int64_t)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||||
#else
|
#else
|
||||||
snprintf(result, BUFFER_LENGTH, "%ld.%06lu",
|
snprintf(result, BUFFER_LENGTH, "%ld.%09lu",
|
||||||
(long)tv->tv_sec, (unsigned long)tv->tv_usec);
|
(long)ts->tv_sec, (unsigned long)ts->tv_nsec);
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -229,11 +245,11 @@ UTI_TimevalToString(struct timeval *tv)
|
||||||
for diagnostic display */
|
for diagnostic display */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
UTI_TimestampToString(NTP_int64 *ts)
|
UTI_TimestampToString(NTP_int64 *ntp_ts)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timespec ts;
|
||||||
UTI_Int64ToTimeval(ts, &tv);
|
UTI_Int64ToTimespec(ntp_ts, &ts);
|
||||||
return UTI_TimevalToString(&tv);
|
return UTI_TimespecToString(&ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
@ -589,13 +605,13 @@ UTI_TimeToLogForm(time_t t)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
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;
|
double elapsed;
|
||||||
|
|
||||||
UTI_DiffTimevalsToDouble(&elapsed, when, old_tv);
|
UTI_DiffTimespecsToDouble(&elapsed, when, old_ts);
|
||||||
*delta_time = elapsed * dfreq - doffset;
|
*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
|
/* Seconds part of NTP timestamp correponding to the origin of the time_t format */
|
||||||
struct timeval format. */
|
|
||||||
#define JAN_1970 0x83aa7e80UL
|
#define JAN_1970 0x83aa7e80UL
|
||||||
|
|
||||||
|
#define NSEC_PER_NTP64 4.294967296
|
||||||
|
|
||||||
void
|
void
|
||||||
UTI_TimevalToInt64(struct timeval *src,
|
UTI_TimespecToInt64(struct timespec *src, NTP_int64 *dest, NTP_int64 *fuzz)
|
||||||
NTP_int64 *dest, NTP_int64 *fuzz)
|
|
||||||
{
|
{
|
||||||
uint32_t hi, lo, sec, usec;
|
uint32_t hi, lo, sec, nsec;
|
||||||
|
|
||||||
sec = (uint32_t)src->tv_sec;
|
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
|
/* Recognize zero as a special case - it always signifies
|
||||||
an 'unknown' value */
|
an 'unknown' value */
|
||||||
if (!usec && !sec) {
|
if (!nsec && !sec) {
|
||||||
hi = lo = 0;
|
hi = lo = 0;
|
||||||
} else {
|
} else {
|
||||||
hi = htonl(sec + JAN_1970);
|
hi = htonl(sec + JAN_1970);
|
||||||
|
lo = htonl(NSEC_PER_NTP64 * nsec);
|
||||||
/* This formula gives an error of about 0.1us worst case */
|
|
||||||
lo = htonl(4295 * usec - (usec >> 5) - (usec >> 9));
|
|
||||||
|
|
||||||
/* Add the fuzz */
|
/* Add the fuzz */
|
||||||
if (fuzz) {
|
if (fuzz) {
|
||||||
|
@ -689,8 +703,7 @@ UTI_TimevalToInt64(struct timeval *src,
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
UTI_Int64ToTimeval(NTP_int64 *src,
|
UTI_Int64ToTimespec(NTP_int64 *src, struct timespec *dest)
|
||||||
struct timeval *dest)
|
|
||||||
{
|
{
|
||||||
uint32_t ntp_sec, ntp_frac;
|
uint32_t ntp_sec, ntp_frac;
|
||||||
|
|
||||||
|
@ -707,10 +720,9 @@ UTI_Int64ToTimeval(NTP_int64 *src,
|
||||||
dest->tv_sec = ntp_sec - JAN_1970;
|
dest->tv_sec = ntp_sec - JAN_1970;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Until I invent a slick way to do this, just do it the obvious way */
|
dest->tv_nsec = ntp_frac / NSEC_PER_NTP64 + 0.5;
|
||||||
dest->tv_usec = (int)(0.5 + (double)(ntp_frac) / 4294.967296);
|
|
||||||
|
|
||||||
UTI_NormaliseTimeval(dest);
|
UTI_NormaliseTimespec(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
@ -722,7 +734,7 @@ UTI_Int64ToTimeval(NTP_int64 *src,
|
||||||
#define MIN_ENDOFTIME_DISTANCE (365 * 24 * 3600)
|
#define MIN_ENDOFTIME_DISTANCE (365 * 24 * 3600)
|
||||||
|
|
||||||
int
|
int
|
||||||
UTI_IsTimeOffsetSane(struct timeval *tv, double offset)
|
UTI_IsTimeOffsetSane(struct timespec *ts, double offset)
|
||||||
{
|
{
|
||||||
double t;
|
double t;
|
||||||
|
|
||||||
|
@ -730,7 +742,7 @@ UTI_IsTimeOffsetSane(struct timeval *tv, double offset)
|
||||||
if (!(offset > -MAX_OFFSET && offset < MAX_OFFSET))
|
if (!(offset > -MAX_OFFSET && offset < MAX_OFFSET))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
UTI_TimevalToDouble(tv, &t);
|
UTI_TimespecToDouble(ts, &t);
|
||||||
t += offset;
|
t += offset;
|
||||||
|
|
||||||
/* Time before 1970 is not considered valid */
|
/* Time before 1970 is not considered valid */
|
||||||
|
@ -769,14 +781,14 @@ UTI_Log2ToDouble(int l)
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
void
|
||||||
UTI_TimevalNetworkToHost(Timeval *src, struct timeval *dest)
|
UTI_TimespecNetworkToHost(Timespec *src, struct timespec *dest)
|
||||||
{
|
{
|
||||||
uint32_t sec_low;
|
uint32_t sec_low;
|
||||||
#ifdef HAVE_LONG_TIME_T
|
#ifdef HAVE_LONG_TIME_T
|
||||||
uint32_t sec_high;
|
uint32_t sec_high;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dest->tv_usec = ntohl(src->tv_nsec) / 1000;
|
dest->tv_nsec = ntohl(src->tv_nsec);
|
||||||
sec_low = ntohl(src->tv_sec_low);
|
sec_low = ntohl(src->tv_sec_low);
|
||||||
#ifdef HAVE_LONG_TIME_T
|
#ifdef HAVE_LONG_TIME_T
|
||||||
sec_high = ntohl(src->tv_sec_high);
|
sec_high = ntohl(src->tv_sec_high);
|
||||||
|
@ -788,15 +800,15 @@ UTI_TimevalNetworkToHost(Timeval *src, struct timeval *dest)
|
||||||
dest->tv_sec = sec_low;
|
dest->tv_sec = sec_low;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UTI_NormaliseTimeval(dest);
|
UTI_NormaliseTimespec(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
void
|
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
|
#ifdef HAVE_LONG_TIME_T
|
||||||
dest->tv_sec_high = htonl((uint64_t)src->tv_sec >> 32);
|
dest->tv_sec_high = htonl((uint64_t)src->tv_sec >> 32);
|
||||||
#else
|
#else
|
||||||
|
|
58
util.h
58
util.h
|
@ -34,6 +34,26 @@
|
||||||
#include "candm.h"
|
#include "candm.h"
|
||||||
#include "hash.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 */
|
/* Convert a timeval into a floating point number of seconds */
|
||||||
extern void UTI_TimevalToDouble(struct timeval *a, double *b);
|
extern void UTI_TimevalToDouble(struct timeval *a, double *b);
|
||||||
|
|
||||||
|
@ -41,34 +61,34 @@ extern void UTI_TimevalToDouble(struct timeval *a, double *b);
|
||||||
timeval */
|
timeval */
|
||||||
extern void UTI_DoubleToTimeval(double a, struct timeval *b);
|
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
|
/* Normalise a struct timeval, by adding or subtracting seconds to bring
|
||||||
its microseconds field into range */
|
its microseconds field into range */
|
||||||
extern void UTI_NormaliseTimeval(struct timeval *x);
|
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 */
|
/* 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 */
|
/* 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
|
the starting time, 'end' is the result that we return. This is
|
||||||
safe to use if start and end are the same */
|
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 */
|
/* Calculate the average and difference (as a double) of two timespecs */
|
||||||
extern void UTI_AverageDiffTimevals(struct timeval *earlier, struct timeval *later, struct timeval *average, double *diff);
|
extern void UTI_AverageDiffTimespecs(struct timespec *earlier, struct timespec *later, struct timespec *average, double *diff);
|
||||||
|
|
||||||
/* Calculate result = a - b + c */
|
/* 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 */
|
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
|
/* Convert an NTP timestamp into a temporary string, largely for
|
||||||
diagnostic display */
|
diagnostic display */
|
||||||
|
@ -95,7 +115,7 @@ extern const char *UTI_SockaddrFamilyToString(int family);
|
||||||
extern char *UTI_TimeToLogForm(time_t t);
|
extern char *UTI_TimeToLogForm(time_t t);
|
||||||
|
|
||||||
/* Adjust time following a frequency/offset change */
|
/* 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 */
|
/* Get zero NTP timestamp with random bits below precision */
|
||||||
extern void UTI_GetInt64Fuzz(NTP_int64 *ts, int 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 double UTI_Int32ToDouble(NTP_int32 x);
|
||||||
extern NTP_int32 UTI_DoubleToInt32(double 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 */
|
/* 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 */
|
/* Get 2 raised to power of a signed integer */
|
||||||
extern double UTI_Log2ToDouble(int l);
|
extern double UTI_Log2ToDouble(int l);
|
||||||
|
|
||||||
extern void UTI_TimevalNetworkToHost(Timeval *src, struct timeval *dest);
|
extern void UTI_TimespecNetworkToHost(Timespec *src, struct timespec *dest);
|
||||||
extern void UTI_TimevalHostToNetwork(struct timeval *src, Timeval *dest);
|
extern void UTI_TimespecHostToNetwork(struct timespec *src, Timespec *dest);
|
||||||
|
|
||||||
extern double UTI_FloatNetworkToHost(Float x);
|
extern double UTI_FloatNetworkToHost(Float x);
|
||||||
extern Float UTI_FloatHostToNetwork(double x);
|
extern Float UTI_FloatHostToNetwork(double x);
|
||||||
|
|
Loading…
Reference in a new issue