from the tracking log file is shown below.
@example
-2012-02-23 05:40:50 158.152.1.76 3 340.529 1.606 1.046e-03 N
+2012-02-23 05:40:50 158.152.1.76 3 340.529 1.606 1.046e-03 N \
+ 4 6.849e-03 -4.670e-04
@end example
The columns are as follows (the quantities in square brackets are the
Leap status (@code{N} means normal, @code{+} means that the last minute
of this month has 61 seconds, @code{-} means that the last minute of the month
has 59 seconds, @code{?} means the clock is not currently synchronised.) [N]
+@item
+The number of combined sources. [4]
+@item
+The estimated standard deviation of the combined offset (in seconds).
+[6.849e-03]
+@item
+The remaining offset correction from the previous update (in seconds, positive
+means the system clock is slow of UTC). [-4.670e-04]
@end enumerate
A banner is periodically written to the log file to indicate the
}
logfileid = CNF_GetLogTracking() ? LOG_FileOpen("tracking",
- " Date (UTC) Time IP Address St Freq ppm Skew ppm Offset L")
+ " Date (UTC) Time IP Address St Freq ppm Skew ppm Offset L Co Offset sd Rem. corr.")
: -1;
max_update_skew = fabs(CNF_GetMaxUpdateSkew()) * 1.0e-6;
/* ================================================== */
static void
-write_log(struct timeval *ref_time, char *ref, int stratum, NTP_Leap leap, double freq, double skew, double offset)
+write_log(struct timeval *ref_time, char *ref, int stratum, NTP_Leap leap,
+ double freq, double skew, double offset, int combined_sources,
+ double offset_sd, double uncorrected_offset)
{
const char leap_codes[4] = {'N', '+', '-', '?'};
if (logfileid != -1) {
- LOG_FileWrite(logfileid, "%s %-15s %2d %10.3f %10.3f %10.3e %1c",
- UTI_TimeToLogForm(ref_time->tv_sec), ref, stratum, freq, skew, offset, leap_codes[leap]);
+ LOG_FileWrite(logfileid, "%s %-15s %2d %10.3f %10.3f %10.3e %1c %2d %10.3e %10.3e",
+ UTI_TimeToLogForm(ref_time->tv_sec), ref, stratum, freq, skew,
+ offset, leap_codes[leap], combined_sources, offset_sd,
+ uncorrected_offset);
}
}
void
REF_SetReference(int stratum,
NTP_Leap leap,
+ int combined_sources,
uint32_t ref_id,
IPAddr *ref_ip,
struct timeval *ref_time,
double update_interval;
double elapsed;
double correction_rate;
+ double uncorrected_offset;
struct timeval now, raw_now, ev_now, ev_raw_now;
assert(initialised);
/* This is cheaper than calling LCL_CookTime */
SCH_GetLastEventTime(&ev_now, NULL, &ev_raw_now);
- UTI_AddDiffToTimeval(&ev_now, &ev_raw_now, &raw_now, &now);
+ UTI_DiffTimevalsToDouble(&uncorrected_offset, &ev_now, &ev_raw_now);
+ UTI_AddDoubleToTimeval(&raw_now, uncorrected_offset, &now);
UTI_DiffTimevalsToDouble(&elapsed, &now, ref_time);
our_offset = offset + elapsed * frequency;
our_leap_status,
abs_freq_ppm,
1.0e6*our_skew,
- our_offset);
+ our_offset,
+ combined_sources,
+ offset_sd,
+ uncorrected_offset);
if (drift_file) {
/* Update drift file at most once per hour */
/* We are not synchronised to an external source, as such. This is
only supposed to be used with the local source option, really
... */
- REF_SetReference(0, LEAP_Unsynchronised, manual_refid, NULL,
+ REF_SetReference(0, LEAP_Unsynchronised, 1, manual_refid, NULL,
ref_time, offset, 0.0, frequency, skew, 0.0, 0.0);
}
REF_SetUnsynchronised(void)
{
/* Variables required for logging to statistics log */
- struct timeval now;
+ struct timeval now, now_raw;
+ double uncorrected_offset;
assert(initialised);
- LCL_ReadCookedTime(&now, NULL);
+ /* This is cheaper than calling LCL_CookTime */
+ SCH_GetLastEventTime(&now, NULL, &now_raw);
+ UTI_DiffTimevalsToDouble(&uncorrected_offset, &now, &now_raw);
if (fb_drifts) {
schedule_fb_drift(&now);
our_leap_status,
LCL_ReadAbsoluteFrequency(),
1.0e6*our_skew,
- 0.0);
+ 0.0,
+ 0,
+ 0.0,
+ uncorrected_offset);
}
/* ================================================== */
/* ================================================== */
-static void
+static int
combine_sources(int n_sel_sources, struct timeval *ref_time, double *offset,
double *offset_sd, double *frequency, double *skew)
{
double src_offset, src_offset_sd, src_frequency, src_skew;
double src_root_delay, src_root_dispersion, elapsed;
double weight, sum_weight, sum_offset, sum2_offset_sd, sum_frequency, sum_skew;
- int i, index;
+ int i, index, combined;
+
+ if (n_sel_sources == 1)
+ return 1;
sum_weight = sum_offset = sum2_offset_sd = sum_frequency = sum_skew = 0.0;
- for (i = 0; i < n_sel_sources; i++) {
+ for (i = combined = 0; i < n_sel_sources; i++) {
index = sel_sources[i];
SST_GetTrackingData(sources[index]->stats, &src_ref_time,
&src_offset, &src_offset_sd,
(src_offset - *offset) * (src_offset - *offset));
sum_frequency += weight * src_frequency;
sum_skew += weight * src_skew;
+
+ combined++;
}
assert(sum_weight > 0.0);
LOG(LOGS_INFO, LOGF_Sources, "combined result offset=%e sd=%e freq=%e skew=%e",
*offset, *offset_sd, *frequency, *skew);
#endif
+
+ return combined;
}
/* ================================================== */
int n_endpoints, j1, j2;
double best_lo, best_hi;
int depth, best_depth;
- int n_sel_sources;
+ int n_sel_sources, combined;
double distance, sel_src_distance;
int stratum, min_stratum;
struct SelectInfo *si;
&src_frequency, &src_skew,
&src_root_delay, &src_root_dispersion);
- if (n_sel_sources > 1) {
- combine_sources(n_sel_sources, &ref_time, &src_offset,
- &src_offset_sd, &src_frequency, &src_skew);
- }
+ combined = combine_sources(n_sel_sources, &ref_time, &src_offset,
+ &src_offset_sd, &src_frequency, &src_skew);
REF_SetReference(sources[selected_source_index]->sel_info.stratum,
leap_status,
+ combined,
sources[selected_source_index]->ref_id,
sources[selected_source_index]->ip_addr,
&ref_time,