Replace integer microseconds in reports with floating-point values

This commit is contained in:
Miroslav Lichvar 2009-12-12 18:44:35 +01:00
parent 5b1a8705cf
commit 2dd9f3373b
7 changed files with 85 additions and 72 deletions

16
candm.h
View file

@ -334,6 +334,7 @@ typedef struct {
Version 4 : IPv6 addressing added, 64-bit time values, sourcestats Version 4 : IPv6 addressing added, 64-bit time values, sourcestats
and tracking reports extended, added flags to NTP source request, and tracking reports extended, added flags to NTP source request,
trimmed source report, replaced fixed-point format with floating-point trimmed source report, replaced fixed-point format with floating-point
and used also instead of integer microseconds
*/ */
@ -471,11 +472,11 @@ typedef struct {
uint16_t state; uint16_t state;
uint16_t mode; uint16_t mode;
uint32_t since_sample; uint32_t since_sample;
int32_t orig_latest_meas; Float orig_latest_meas;
int32_t latest_meas; Float latest_meas;
uint32_t latest_meas_err; Float latest_meas_err;
int32_t est_offset; Float est_offset;
uint32_t est_offset_err; Float est_offset_err;
int32_t EOR; int32_t EOR;
} RPY_Source_Data; } RPY_Source_Data;
@ -484,8 +485,7 @@ typedef struct {
IPAddr ip_addr; IPAddr ip_addr;
uint32_t stratum; uint32_t stratum;
Timeval ref_time; Timeval ref_time;
uint32_t current_correction_s; Float current_correction;
uint32_t current_correction_us;
Float freq_ppm; Float freq_ppm;
Float resid_freq_ppm; Float resid_freq_ppm;
Float skew_ppm; Float skew_ppm;
@ -500,7 +500,7 @@ typedef struct {
uint32_t n_samples; uint32_t n_samples;
uint32_t n_runs; uint32_t n_runs;
uint32_t span_seconds; uint32_t span_seconds;
uint32_t sd_us; Float sd;
Float resid_freq_ppm; Float resid_freq_ppm;
Float skew_ppm; Float skew_ppm;
int32_t EOR; int32_t EOR;

View file

@ -3540,7 +3540,8 @@ source. This is normally in seconds. The letters @code{m}, @code{h},
@item Last sample @item Last sample
This column shows the offset between the local clock and the source at This column shows the offset between the local clock and the source at
the last measurement. The number in the square brackets shows the the last measurement. The number in the square brackets shows the
actual measured offset. This may be suffixed by @code{us} (indicating actual measured offset. This may be suffixed by @code{ns} (indicating
nanoseconds), @code{us} (indicating
microseconds), @code{ms} (indicating milliseconds), or @code{s} microseconds), @code{ms} (indicating milliseconds), or @code{s}
(indicating seconds). The number to the left of the square brackets (indicating seconds). The number to the left of the square brackets
shows the original measurement, adjusted to allow for any slews applied shows the original measurement, adjusted to allow for any slews applied
@ -3623,7 +3624,7 @@ performance. An example of the output is shown below.
Reference ID : 1.2.3.4 (a.b.c) Reference ID : 1.2.3.4 (a.b.c)
Stratum : 3 Stratum : 3
Ref time (UTC) : Sun May 17 06:13:11 1998 Ref time (UTC) : Sun May 17 06:13:11 1998
System time : 0.000000 seconds fast of NTP time System time : 0.000000000 seconds fast of NTP time
Frequency : 331.898 ppm fast Frequency : 331.898 ppm fast
Residual freq : 0.004 ppm Residual freq : 0.004 ppm
Skew : 0.154 ppm Skew : 0.154 ppm

View file

@ -1481,31 +1481,51 @@ print_seconds(unsigned long s)
/* ================================================== */ /* ================================================== */
static void static void
print_microseconds(unsigned long us) print_nanoseconds(double s)
{ {
if (us <= 9999) { unsigned long ms, ns;
printf("%4ldus", us);
} else if (us <= 9999999) { ns = s * 1e9 + 0.5;
printf("%4ldms", us / 1000); ms = s * 1e3 + 0.5;
} else if (us <= 999999999) {
printf("%3ld.%01lds", us / 1000000, (us/100000) % 10); if (ns <= 9999) {
printf("%4ldns", ns);
} else if (ns <= 9999499) {
printf("%4ldus", (ns + 500) / 1000);
} else if (ms <= 9999) {
printf("%4ldms", ms);
} else if (ms <= 999949) {
printf("%3ld.%01lds", (ms + 50) / 1000, ((ms + 50) / 100) % 10);
} else { } else {
printf("%5lds", us / 1000000); printf("%5lds", (ms + 500) / 1000);
} }
} }
/* ================================================== */ /* ================================================== */
static void static void
print_signed_microseconds(long us) print_signed_nanoseconds(double s)
{ {
long x = abs(us); long ms, ns, sign;
if (x <= 9999) {
printf("%+5ldus", us); if (s >= 0.0) {
} else if (x <= 9999999) { ns = s * 1e9 + 0.5;
printf("%+5ldms", us / 1000); ms = s * 1e3 + 0.5;
sign = 1;
} else { } else {
printf("%+6lds", us / 1000000); ns = -s * 1e9 + 0.5;
ms = -s * 1e3 + 0.5;
sign = -1;
}
if (ns <= 9999) {
printf("%+5ldns", ns * sign);
} else if (ns <= 9999499) {
printf("%+5ldus", (ns + 500) / 1000 * sign);
} else if (ms <= 9999) {
printf("%+5ldms", ms * sign);
} else {
printf("%+6lds", (ms + 500) / 1000 * sign);
} }
} }
@ -1533,9 +1553,9 @@ process_cmd_sources(char *line)
int n_sources, i; int n_sources, i;
int verbose = 0; int verbose = 0;
int32_t orig_latest_meas, latest_meas, est_offset; double orig_latest_meas, latest_meas, est_offset;
IPAddr ip_addr; IPAddr ip_addr;
uint32_t latest_meas_err, est_offset_err; double latest_meas_err, est_offset_err;
uint32_t latest_meas_ago; uint32_t latest_meas_ago;
uint16_t poll, stratum; uint16_t poll, stratum;
uint16_t state, mode; uint16_t state, mode;
@ -1575,11 +1595,11 @@ process_cmd_sources(char *line)
state = ntohs(reply.data.source_data.state); state = ntohs(reply.data.source_data.state);
mode = ntohs(reply.data.source_data.mode); mode = ntohs(reply.data.source_data.mode);
latest_meas_ago = ntohl(reply.data.source_data.since_sample); latest_meas_ago = ntohl(reply.data.source_data.since_sample);
orig_latest_meas = ntohl(reply.data.source_data.orig_latest_meas); orig_latest_meas = UTI_FloatNetworkToHost(reply.data.source_data.orig_latest_meas);
latest_meas = ntohl(reply.data.source_data.latest_meas); latest_meas = UTI_FloatNetworkToHost(reply.data.source_data.latest_meas);
latest_meas_err = ntohl(reply.data.source_data.latest_meas_err); latest_meas_err = UTI_FloatNetworkToHost(reply.data.source_data.latest_meas_err);
est_offset = ntohl(reply.data.source_data.est_offset); est_offset = UTI_FloatNetworkToHost(reply.data.source_data.est_offset);
est_offset_err = ntohl(reply.data.source_data.est_offset_err); est_offset_err = UTI_FloatNetworkToHost(reply.data.source_data.est_offset_err);
if (mode == RPY_SD_MD_REF) { if (mode == RPY_SD_MD_REF) {
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ip_addr.addr.in4)); snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ip_addr.addr.in4));
@ -1614,12 +1634,12 @@ process_cmd_sources(char *line)
printf(" %-25s %2d %2d ", hostname_buf, stratum, poll); printf(" %-25s %2d %2d ", hostname_buf, stratum, poll);
print_seconds(latest_meas_ago); print_seconds(latest_meas_ago);
printf(" "); printf(" ");
print_signed_microseconds(latest_meas); print_signed_nanoseconds(latest_meas);
printf("["); printf("[");
print_signed_microseconds(orig_latest_meas); print_signed_nanoseconds(orig_latest_meas);
printf("]"); printf("]");
printf(" +/- "); printf(" +/- ");
print_microseconds(latest_meas_err); print_nanoseconds(latest_meas_err);
printf("\n"); printf("\n");
} else { } else {
return 0; return 0;
@ -1643,8 +1663,7 @@ process_cmd_sourcestats(char *line)
char hostname_buf[32]; char hostname_buf[32];
unsigned long n_samples, n_runs, span_seconds; unsigned long n_samples, n_runs, span_seconds;
double resid_freq_ppm, skew_ppm; double resid_freq_ppm, skew_ppm, sd;
unsigned long sd_us;
unsigned long ref_id; unsigned long ref_id;
IPAddr ip_addr; IPAddr ip_addr;
@ -1679,9 +1698,9 @@ process_cmd_sourcestats(char *line)
n_samples = ntohl(reply.data.sourcestats.n_samples); n_samples = ntohl(reply.data.sourcestats.n_samples);
n_runs = ntohl(reply.data.sourcestats.n_runs); n_runs = ntohl(reply.data.sourcestats.n_runs);
span_seconds = ntohl(reply.data.sourcestats.span_seconds); span_seconds = ntohl(reply.data.sourcestats.span_seconds);
sd_us = ntohl(reply.data.sourcestats.sd_us);
resid_freq_ppm = UTI_FloatNetworkToHost(reply.data.sourcestats.resid_freq_ppm); resid_freq_ppm = UTI_FloatNetworkToHost(reply.data.sourcestats.resid_freq_ppm);
skew_ppm = UTI_FloatNetworkToHost(reply.data.sourcestats.skew_ppm); skew_ppm = UTI_FloatNetworkToHost(reply.data.sourcestats.skew_ppm);
sd = UTI_FloatNetworkToHost(reply.data.sourcestats.sd);
if (ip_addr.family == IPADDR_UNSPEC) if (ip_addr.family == IPADDR_UNSPEC)
snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ref_id)); snprintf(hostname_buf, sizeof(hostname_buf), "%s", UTI_RefidToString(ref_id));
@ -1695,7 +1714,7 @@ process_cmd_sourcestats(char *line)
printf("%-25s %2lu %2lu ", hostname_buf, n_samples, n_runs); printf("%-25s %2lu %2lu ", hostname_buf, n_samples, n_runs);
print_seconds(span_seconds); print_seconds(span_seconds);
printf(" %10.3f %10.3f ", resid_freq_ppm, skew_ppm); printf(" %10.3f %10.3f ", resid_freq_ppm, skew_ppm);
print_microseconds(sd_us); print_nanoseconds(sd);
printf("\n"); printf("\n");
} else { } else {
return 0; return 0;
@ -1721,7 +1740,6 @@ process_cmd_tracking(char *line)
struct timeval ref_time; struct timeval ref_time;
struct tm ref_time_tm; struct tm ref_time_tm;
unsigned long a, b, c, d; unsigned long a, b, c, d;
struct timeval correction_tv;
double correction; double correction;
double freq_ppm; double freq_ppm;
double resid_freq_ppm; double resid_freq_ppm;
@ -1752,10 +1770,8 @@ process_cmd_tracking(char *line)
UTI_TimevalNetworkToHost(&reply.data.tracking.ref_time, &ref_time); UTI_TimevalNetworkToHost(&reply.data.tracking.ref_time, &ref_time);
ref_time_tm = *gmtime((time_t *)&ref_time.tv_sec); ref_time_tm = *gmtime((time_t *)&ref_time.tv_sec);
printf("Ref time (UTC) : %s", asctime(&ref_time_tm)); printf("Ref time (UTC) : %s", asctime(&ref_time_tm));
correction_tv.tv_sec = (int32_t)ntohl(reply.data.tracking.current_correction_s); correction = UTI_FloatNetworkToHost(reply.data.tracking.current_correction);
correction_tv.tv_usec = ntohl(reply.data.tracking.current_correction_us); printf("System time : %.9f seconds %s of NTP time\n", fabs(correction),
correction = (double) correction_tv.tv_sec + 1.0e-6 * correction_tv.tv_usec;
printf("System time : %.6f seconds %s of NTP time\n", fabs(correction),
(correction > 0.0) ? "slow" : "fast"); (correction > 0.0) ? "slow" : "fast");
freq_ppm = UTI_FloatNetworkToHost(reply.data.tracking.freq_ppm); freq_ppm = UTI_FloatNetworkToHost(reply.data.tracking.freq_ppm);
resid_freq_ppm = UTI_FloatNetworkToHost(reply.data.tracking.resid_freq_ppm); resid_freq_ppm = UTI_FloatNetworkToHost(reply.data.tracking.resid_freq_ppm);

View file

@ -1040,12 +1040,11 @@ handle_source_data(CMD_Request *rx_message, CMD_Reply *tx_message)
break; break;
} }
tx_message->data.source_data.since_sample = htonl(report.latest_meas_ago); tx_message->data.source_data.since_sample = htonl(report.latest_meas_ago);
tx_message->data.source_data.orig_latest_meas = htonl(report.orig_latest_meas); tx_message->data.source_data.orig_latest_meas = UTI_FloatHostToNetwork(report.orig_latest_meas);
tx_message->data.source_data.latest_meas = htonl(report.latest_meas); tx_message->data.source_data.latest_meas = UTI_FloatHostToNetwork(report.latest_meas);
tx_message->data.source_data.latest_meas_err = htonl(report.latest_meas_err); tx_message->data.source_data.latest_meas_err = UTI_FloatHostToNetwork(report.latest_meas_err);
tx_message->data.source_data.est_offset = htonl(report.est_offset); tx_message->data.source_data.est_offset = UTI_FloatHostToNetwork(report.est_offset);
tx_message->data.source_data.est_offset_err = htonl(report.est_offset_err); tx_message->data.source_data.est_offset_err = UTI_FloatHostToNetwork(report.est_offset_err);
} else { } else {
tx_message->status = htons(STT_NOSUCHSOURCE); tx_message->status = htons(STT_NOSUCHSOURCE);
} }
@ -1381,8 +1380,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 = htonl(rpt.stratum); tx_message->data.tracking.stratum = htonl(rpt.stratum);
UTI_TimevalHostToNetwork(&rpt.ref_time, &tx_message->data.tracking.ref_time); UTI_TimevalHostToNetwork(&rpt.ref_time, &tx_message->data.tracking.ref_time);
tx_message->data.tracking.current_correction_s = htonl(rpt.current_correction.tv_sec); tx_message->data.tracking.current_correction = UTI_FloatHostToNetwork(rpt.current_correction);
tx_message->data.tracking.current_correction_us = htonl(rpt.current_correction.tv_usec);
tx_message->data.tracking.freq_ppm = UTI_FloatHostToNetwork(rpt.freq_ppm); tx_message->data.tracking.freq_ppm = UTI_FloatHostToNetwork(rpt.freq_ppm);
tx_message->data.tracking.resid_freq_ppm = UTI_FloatHostToNetwork(rpt.resid_freq_ppm); tx_message->data.tracking.resid_freq_ppm = UTI_FloatHostToNetwork(rpt.resid_freq_ppm);
tx_message->data.tracking.skew_ppm = UTI_FloatHostToNetwork(rpt.skew_ppm); tx_message->data.tracking.skew_ppm = UTI_FloatHostToNetwork(rpt.skew_ppm);
@ -1408,9 +1406,9 @@ handle_sourcestats(CMD_Request *rx_message, CMD_Reply *tx_message)
tx_message->data.sourcestats.n_samples = htonl(report.n_samples); tx_message->data.sourcestats.n_samples = htonl(report.n_samples);
tx_message->data.sourcestats.n_runs = htonl(report.n_runs); tx_message->data.sourcestats.n_runs = htonl(report.n_runs);
tx_message->data.sourcestats.span_seconds = htonl(report.span_seconds); tx_message->data.sourcestats.span_seconds = htonl(report.span_seconds);
tx_message->data.sourcestats.sd_us = htonl((unsigned long) (0.5 + report.sd_us));
tx_message->data.sourcestats.resid_freq_ppm = UTI_FloatHostToNetwork(report.resid_freq_ppm); tx_message->data.sourcestats.resid_freq_ppm = UTI_FloatHostToNetwork(report.resid_freq_ppm);
tx_message->data.sourcestats.skew_ppm = UTI_FloatHostToNetwork(report.skew_ppm); tx_message->data.sourcestats.skew_ppm = UTI_FloatHostToNetwork(report.skew_ppm);
tx_message->data.sourcestats.sd = UTI_FloatHostToNetwork(report.sd);
} else { } else {
tx_message->status = htons(STT_NOSUCHSOURCE); tx_message->status = htons(STT_NOSUCHSOURCE);
} }

View file

@ -725,7 +725,7 @@ REF_GetTrackingReport(RPT_TrackingReport *rep)
rep->ip_addr = our_ref_ip; rep->ip_addr = our_ref_ip;
rep->stratum = our_stratum; rep->stratum = our_stratum;
rep->ref_time = our_ref_time; rep->ref_time = our_ref_time;
UTI_DoubleToTimeval(correction, &rep->current_correction); rep->current_correction = correction;
rep->freq_ppm = LCL_ReadAbsoluteFrequency(); rep->freq_ppm = LCL_ReadAbsoluteFrequency();
rep->resid_freq_ppm = 1.0e6 * our_residual_freq; rep->resid_freq_ppm = 1.0e6 * our_residual_freq;
rep->skew_ppm = 1.0e6 * our_skew; rep->skew_ppm = 1.0e6 * our_skew;
@ -738,7 +738,7 @@ REF_GetTrackingReport(RPT_TrackingReport *rep)
rep->ip_addr.family = IPADDR_UNSPEC; rep->ip_addr.family = IPADDR_UNSPEC;
rep->stratum = local_stratum; rep->stratum = local_stratum;
rep->ref_time = now_cooked; rep->ref_time = now_cooked;
UTI_DoubleToTimeval(correction, &rep->current_correction); rep->current_correction = correction;
rep->freq_ppm = LCL_ReadAbsoluteFrequency(); rep->freq_ppm = LCL_ReadAbsoluteFrequency();
rep->resid_freq_ppm = 0.0; rep->resid_freq_ppm = 0.0;
rep->skew_ppm = 0.0; rep->skew_ppm = 0.0;
@ -752,7 +752,7 @@ REF_GetTrackingReport(RPT_TrackingReport *rep)
rep->stratum = 0; rep->stratum = 0;
rep->ref_time.tv_sec = 0; rep->ref_time.tv_sec = 0;
rep->ref_time.tv_usec = 0; rep->ref_time.tv_usec = 0;
UTI_DoubleToTimeval(correction, &rep->current_correction); rep->current_correction = correction;
rep->freq_ppm = LCL_ReadAbsoluteFrequency(); rep->freq_ppm = LCL_ReadAbsoluteFrequency();
rep->resid_freq_ppm = 0.0; rep->resid_freq_ppm = 0.0;
rep->skew_ppm = 0.0; rep->skew_ppm = 0.0;

View file

@ -44,11 +44,11 @@ typedef struct {
enum {RPT_SYNC, RPT_UNREACH, RPT_FALSETICKER, RPT_JITTERY, RPT_OTHER} state; enum {RPT_SYNC, RPT_UNREACH, RPT_FALSETICKER, RPT_JITTERY, RPT_OTHER} state;
unsigned long latest_meas_ago; /* seconds */ unsigned long latest_meas_ago; /* seconds */
long orig_latest_meas; /* microseconds (us) */ double orig_latest_meas; /* seconds */
long latest_meas; /* us */ double latest_meas; /* seconds */
unsigned long latest_meas_err; /* us */ double latest_meas_err; /* seconds */
long est_offset; /* us */ double est_offset; /* seconds */
unsigned long est_offset_err; /* us */ double est_offset_err; /* seconds */
} RPT_SourceReport ; } RPT_SourceReport ;
typedef struct { typedef struct {
@ -56,7 +56,7 @@ typedef struct {
IPAddr ip_addr; IPAddr ip_addr;
unsigned long stratum; unsigned long stratum;
struct timeval ref_time; struct timeval ref_time;
struct timeval current_correction; double current_correction;
double freq_ppm; double freq_ppm;
double resid_freq_ppm; double resid_freq_ppm;
double skew_ppm; double skew_ppm;
@ -72,7 +72,7 @@ typedef struct {
unsigned long span_seconds; unsigned long span_seconds;
double resid_freq_ppm; double resid_freq_ppm;
double skew_ppm; double skew_ppm;
double sd_us; double sd;
} RPT_SourcestatsReport; } RPT_SourcestatsReport;
typedef struct { typedef struct {

View file

@ -846,14 +846,14 @@ void
SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now) SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now)
{ {
int n, nb; int n, nb;
double est_offset, est_err, elapsed, sample_elapsed; double elapsed, sample_elapsed;
struct timeval ago; struct timeval ago;
if (inst->n_samples > 0) { if (inst->n_samples > 0) {
n = inst->n_samples - 1; n = inst->n_samples - 1;
report->orig_latest_meas = (long)(0.5 + 1.0e6 * inst->orig_offsets[n]); report->orig_latest_meas = inst->orig_offsets[n];
report->latest_meas = (long)(0.5 + 1.0e6 * inst->offsets[n]); report->latest_meas = inst->offsets[n];
report->latest_meas_err = (unsigned long)(0.5 + 1.0e6 * (0.5*inst->root_delays[n] + inst->root_dispersions[n])); report->latest_meas_err = 0.5*inst->root_delays[n] + inst->root_dispersions[n];
report->stratum = inst->strata[n]; report->stratum = inst->strata[n];
UTI_DiffTimevals(&ago, now, &inst->sample_times[n]); UTI_DiffTimevals(&ago, now, &inst->sample_times[n]);
@ -863,12 +863,10 @@ SST_DoSourceReport(SST_Stats inst, RPT_SourceReport *report, struct timeval *now
UTI_DiffTimevalsToDouble(&elapsed, now, &inst->offset_time); UTI_DiffTimevalsToDouble(&elapsed, now, &inst->offset_time);
nb = inst->best_single_sample; nb = inst->best_single_sample;
UTI_DiffTimevalsToDouble(&sample_elapsed, now, &(inst->sample_times[nb])); UTI_DiffTimevalsToDouble(&sample_elapsed, now, &(inst->sample_times[nb]));
est_offset = inst->estimated_offset + elapsed * inst->estimated_frequency; report->est_offset = inst->estimated_offset + elapsed * inst->estimated_frequency;
est_err = (inst->estimated_offset_sd + report->est_offset_err = (inst->estimated_offset_sd +
sample_elapsed * inst->skew + sample_elapsed * inst->skew +
(0.5*inst->root_delays[nb] + inst->root_dispersions[nb])); (0.5*inst->root_delays[nb] + inst->root_dispersions[nb]));
report->est_offset = (long)(0.5 + 1.0e6 * est_offset);
report->est_offset_err = (unsigned long) (0.5 + 1.0e6 * est_err);
} else { } else {
report->est_offset = report->latest_meas; report->est_offset = report->latest_meas;
report->est_offset_err = report->latest_meas_err; report->est_offset_err = report->latest_meas_err;
@ -913,7 +911,7 @@ SST_DoSourcestatsReport(SST_Stats inst, RPT_SourcestatsReport *report)
report->resid_freq_ppm = 1.0e6 * inst->estimated_frequency; report->resid_freq_ppm = 1.0e6 * inst->estimated_frequency;
report->skew_ppm = 1.0e6 * inst->skew; report->skew_ppm = 1.0e6 * inst->skew;
report->sd_us = 1.0e6 * sqrt(inst->variance); report->sd = sqrt(inst->variance);
} }
/* ================================================== */ /* ================================================== */