From e14a03a1723a7080a8838df5dd2a613fd7ebf7e5 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Tue, 9 Dec 2014 15:42:56 +0100 Subject: [PATCH] local: add new driver call to set synchronization status This will be used to set the kernel adjtimex() variables to allow other applications running on the system to know if the system clock is synchronized and the estimated error and the maximum error. --- local.c | 15 ++++++++++++++- local.h | 4 ++++ localp.h | 6 +++++- reference.c | 4 ++++ sys_generic.c | 5 +++-- sys_generic.h | 3 ++- sys_linux.c | 2 +- sys_netbsd.c | 3 ++- sys_solaris.c | 3 ++- sys_sunos.c | 3 ++- 10 files changed, 39 insertions(+), 9 deletions(-) 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 */