diff --git a/local.c b/local.c index d5762d9..c7b742a 100644 --- a/local.c +++ b/local.c @@ -56,6 +56,7 @@ static lcl_AccrueOffsetDriver drv_accrue_offset; static lcl_ApplyStepOffsetDriver drv_apply_step_offset; static lcl_OffsetCorrectionDriver drv_offset_convert; static lcl_SetLeapDriver drv_set_leap; +static lcl_SetSyncStatusDriver drv_set_sync_status; /* ================================================== */ @@ -557,7 +558,8 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq, lcl_AccrueOffsetDriver accrue_offset, lcl_ApplyStepOffsetDriver apply_step_offset, lcl_OffsetCorrectionDriver offset_convert, - lcl_SetLeapDriver set_leap) + lcl_SetLeapDriver set_leap, + lcl_SetSyncStatusDriver set_sync_status) { drv_read_freq = read_freq; drv_set_freq = set_freq; @@ -565,6 +567,7 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq, drv_apply_step_offset = apply_step_offset; drv_offset_convert = offset_convert; drv_set_leap = set_leap; + drv_set_sync_status = set_sync_status; current_freq_ppm = (*drv_read_freq)(); @@ -632,3 +635,13 @@ LCL_SetTempComp(double comp) } /* ================================================== */ + +void +LCL_SetSyncStatus(int synchronised, double est_error, double max_error) +{ + if (drv_set_sync_status) { + (drv_set_sync_status)(synchronised, est_error, max_error); + } +} + +/* ================================================== */ diff --git a/local.h b/local.h index aff9004..f0c3516 100644 --- a/local.h +++ b/local.h @@ -206,4 +206,8 @@ extern void LCL_SetLeap(int leap); due to clamping or rounding). */ extern double LCL_SetTempComp(double comp); +/* Routine to update the synchronisation status in the kernel to allow other + applications to know if the system clock is synchronised and error bounds */ +extern void LCL_SetSyncStatus(int synchronised, double est_error, double max_error); + #endif /* GOT_LOCAL_H */ diff --git a/localp.h b/localp.h index ce92f1c..321985e 100644 --- a/localp.h +++ b/localp.h @@ -57,6 +57,9 @@ typedef void (*lcl_OffsetCorrectionDriver)(struct timeval *raw, double *corr, do /* System driver to schedule leap second */ typedef void (*lcl_SetLeapDriver)(int leap); +/* System driver to set the synchronisation status */ +typedef void (*lcl_SetSyncStatusDriver)(int synchronised, double est_error, double max_error); + extern void lcl_InvokeDispersionNotifyHandlers(double dispersion); extern void @@ -65,6 +68,7 @@ lcl_RegisterSystemDrivers(lcl_ReadFrequencyDriver read_freq, lcl_AccrueOffsetDriver accrue_offset, lcl_ApplyStepOffsetDriver apply_step_offset, lcl_OffsetCorrectionDriver offset_convert, - lcl_SetLeapDriver set_leap); + lcl_SetLeapDriver set_leap, + lcl_SetSyncStatusDriver set_sync_status); #endif /* GOT_LOCALP_H */ diff --git a/reference.c b/reference.c index 0103c38..e6b4bd5 100644 --- a/reference.c +++ b/reference.c @@ -928,6 +928,8 @@ REF_SetReference(int stratum, LOG(LOGS_WARN, LOGF_Reference, "System clock was stepped by %.6f seconds", -step_offset); } + LCL_SetSyncStatus(are_we_synchronised, offset_sd, offset_sd + root_delay / 2.0 + root_dispersion); + abs_freq_ppm = LCL_ReadAbsoluteFrequency(); write_log(&now, @@ -1016,6 +1018,8 @@ REF_SetUnsynchronised(void) update_leap_status(LEAP_Unsynchronised, 0); are_we_synchronised = 0; + LCL_SetSyncStatus(0, 0.0, 0.0); + write_log(&now, "0.0.0.0", 0, diff --git a/sys_generic.c b/sys_generic.c index 2adbbfe..3cdb184 100644 --- a/sys_generic.c +++ b/sys_generic.c @@ -275,7 +275,8 @@ SYS_Generic_CompleteFreqDriver(double max_set_freq_ppm, double max_set_freq_dela lcl_ReadFrequencyDriver sys_read_freq, lcl_SetFrequencyDriver sys_set_freq, lcl_ApplyStepOffsetDriver sys_apply_step_offset, - lcl_SetLeapDriver sys_set_leap) + lcl_SetLeapDriver sys_set_leap, + lcl_SetSyncStatusDriver sys_set_sync_status) { max_freq = max_set_freq_ppm; max_freq_change_delay = max_set_freq_delay * (1.0 + max_freq / 1.0e6); @@ -291,7 +292,7 @@ SYS_Generic_CompleteFreqDriver(double max_set_freq_ppm, double max_set_freq_dela lcl_RegisterSystemDrivers(read_frequency, set_frequency, accrue_offset, sys_apply_step_offset ? sys_apply_step_offset : apply_step_offset, - offset_convert, sys_set_leap); + offset_convert, sys_set_leap, NULL); LCL_AddParameterChangeHandler(handle_step, NULL); } diff --git a/sys_generic.h b/sys_generic.h index 45c14e2..4532083 100644 --- a/sys_generic.h +++ b/sys_generic.h @@ -35,7 +35,8 @@ extern void SYS_Generic_CompleteFreqDriver(double max_set_freq_ppm, double max_s lcl_ReadFrequencyDriver sys_read_freq, lcl_SetFrequencyDriver sys_set_freq, lcl_ApplyStepOffsetDriver sys_apply_step_offset, - lcl_SetLeapDriver sys_set_leap); + lcl_SetLeapDriver sys_set_leap, + lcl_SetSyncStatusDriver sys_set_sync_status); extern void SYS_Generic_Finalise(void); diff --git a/sys_linux.c b/sys_linux.c index b342505..d2091b9 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -338,7 +338,7 @@ SYS_Linux_Initialise(void) 1.0 / tick_update_hz, read_frequency, set_frequency, have_setoffset ? apply_step_offset : NULL, - set_leap); + set_leap, NULL); } /* ================================================== */ diff --git a/sys_netbsd.c b/sys_netbsd.c index 8c08d4e..c54de3f 100644 --- a/sys_netbsd.c +++ b/sys_netbsd.c @@ -307,7 +307,8 @@ SYS_NetBSD_Initialise(void) lcl_RegisterSystemDrivers(read_frequency, set_frequency, accrue_offset, apply_step_offset, get_offset_correction, - NULL /* set_leap */); + NULL /* set_leap */, + NULL /* set_sync_status */); } diff --git a/sys_solaris.c b/sys_solaris.c index 0c8dedb..2802a90 100644 --- a/sys_solaris.c +++ b/sys_solaris.c @@ -426,7 +426,8 @@ SYS_Solaris_Initialise(void) lcl_RegisterSystemDrivers(read_frequency, set_frequency, accrue_offset, apply_step_offset, get_offset_correction, - NULL /* set_leap */); + NULL /* set_leap */, + NULL /* set_sync_status */); /* Turn off the kernel switch that keeps the system clock in step with the non-volatile clock */ diff --git a/sys_sunos.c b/sys_sunos.c index d45f58f..9231dca 100644 --- a/sys_sunos.c +++ b/sys_sunos.c @@ -379,7 +379,8 @@ SYS_SunOS_Initialise(void) lcl_RegisterSystemDrivers(read_frequency, set_frequency, accrue_offset, apply_step_offset, get_offset_correction, - NULL /* set_leap */); + NULL /* set_leap */, + NULL /* set_sync_status */); /* Turn off the kernel switch that keeps the system clock in step with the non-volatile clock */