sys: add sync status setting to generic and Linux driver
Set the adjtimex status, esterror and maxerror fields to the values provided by the reference module.
This commit is contained in:
parent
2645e632a8
commit
02cbe5e1ad
5 changed files with 54 additions and 17 deletions
|
@ -38,6 +38,7 @@ struct timex {
|
|||
#define ADJ_OFFSET 0x0001 /* time offset */
|
||||
#define ADJ_FREQUENCY 0x0002 /* frequency offset */
|
||||
#define ADJ_MAXERROR 0x0004 /* maximum time error */
|
||||
#define ADJ_ESTERROR 0x0008 /* estimated time error */
|
||||
#define ADJ_STATUS 0x0010 /* clock status */
|
||||
#define ADJ_TIMECONST 0x0020 /* pll time constant */
|
||||
#define ADJ_SETOFFSET 0x0100 /* add 'time' to current time */
|
||||
|
|
|
@ -39,9 +39,10 @@
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
/* System clock frequency drivers */
|
||||
/* System clock drivers */
|
||||
static lcl_ReadFrequencyDriver drv_read_freq;
|
||||
static lcl_SetFrequencyDriver drv_set_freq;
|
||||
static lcl_SetSyncStatusDriver drv_set_sync_status;
|
||||
|
||||
/* Current frequency as requested by the local module (in ppm) */
|
||||
static double base_freq;
|
||||
|
@ -270,6 +271,22 @@ apply_step_offset(double offset)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
set_sync_status(int synchronised, double est_error, double max_error)
|
||||
{
|
||||
double offset;
|
||||
|
||||
offset = fabs(offset_register);
|
||||
if (est_error < offset)
|
||||
est_error = offset;
|
||||
max_error += offset;
|
||||
|
||||
if (drv_set_sync_status)
|
||||
drv_set_sync_status(synchronised, est_error, max_error);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
SYS_Generic_CompleteFreqDriver(double max_set_freq_ppm, double max_set_freq_delay,
|
||||
lcl_ReadFrequencyDriver sys_read_freq,
|
||||
|
@ -282,6 +299,7 @@ SYS_Generic_CompleteFreqDriver(double max_set_freq_ppm, double max_set_freq_dela
|
|||
max_freq_change_delay = max_set_freq_delay * (1.0 + max_freq / 1.0e6);
|
||||
drv_read_freq = sys_read_freq;
|
||||
drv_set_freq = sys_set_freq;
|
||||
drv_set_sync_status = sys_set_sync_status;
|
||||
|
||||
base_freq = (*drv_read_freq)();
|
||||
slew_freq = 0.0;
|
||||
|
@ -292,7 +310,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, NULL);
|
||||
offset_convert, sys_set_leap, set_sync_status);
|
||||
|
||||
LCL_AddParameterChangeHandler(handle_step, NULL);
|
||||
}
|
||||
|
|
30
sys_linux.c
30
sys_linux.c
|
@ -58,6 +58,9 @@ int LockAll = 0;
|
|||
#include "logging.h"
|
||||
#include "wrap_adjtimex.h"
|
||||
|
||||
/* The threshold for adjtimex maxerror when the kernel sets the UNSYNC flag */
|
||||
#define UNSYNC_MAXERROR 16.0
|
||||
|
||||
/* This is the uncompensated system tick value */
|
||||
static int nominal_tick;
|
||||
|
||||
|
@ -181,6 +184,29 @@ set_leap(int leap)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
set_sync_status(int synchronised, double est_error, double max_error)
|
||||
{
|
||||
if (synchronised) {
|
||||
if (est_error > UNSYNC_MAXERROR)
|
||||
est_error = UNSYNC_MAXERROR;
|
||||
if (max_error >= UNSYNC_MAXERROR) {
|
||||
max_error = UNSYNC_MAXERROR;
|
||||
synchronised = 0;
|
||||
}
|
||||
} else {
|
||||
est_error = max_error = UNSYNC_MAXERROR;
|
||||
}
|
||||
|
||||
/* Clear the UNSYNC flag only if rtcsync is enabled */
|
||||
if (!CNF_GetRtcSync())
|
||||
synchronised = 0;
|
||||
|
||||
TMX_SetSync(synchronised, est_error, max_error);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
||||
/* Estimate the value of USER_HZ given the value of txc.tick that chronyd finds when
|
||||
* it starts. The only credible values are 100 (Linux/x86) or powers of 2.
|
||||
* Also, the bounds checking inside the kernel's adjtimex system call enforces
|
||||
|
@ -334,13 +360,11 @@ SYS_Linux_Initialise(void)
|
|||
have_setoffset = 0;
|
||||
}
|
||||
|
||||
TMX_SetSync(CNF_GetRtcSync());
|
||||
|
||||
SYS_Generic_CompleteFreqDriver(1.0e6 * max_tick_bias / nominal_tick,
|
||||
1.0 / tick_update_hz,
|
||||
read_frequency, set_frequency,
|
||||
have_setoffset ? apply_step_offset : NULL,
|
||||
set_leap, NULL);
|
||||
set_leap, set_sync_status);
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
|
@ -68,19 +68,11 @@ TMX_SetFrequency(double *freq, long tick)
|
|||
{
|
||||
struct timex txc;
|
||||
|
||||
txc.modes = ADJ_TICK | ADJ_FREQUENCY | ADJ_STATUS;
|
||||
txc.modes = ADJ_TICK | ADJ_FREQUENCY;
|
||||
|
||||
txc.freq = (long)(*freq * (double)(1 << SHIFT_USEC));
|
||||
*freq = txc.freq / (double)(1 << SHIFT_USEC);
|
||||
txc.tick = tick;
|
||||
txc.status = status;
|
||||
|
||||
if (!(status & STA_UNSYNC)) {
|
||||
/* maxerror has to be reset periodically to prevent kernel
|
||||
from enabling UNSYNC flag */
|
||||
txc.modes |= ADJ_MAXERROR;
|
||||
txc.maxerror = 0;
|
||||
}
|
||||
|
||||
return adjtimex(&txc);
|
||||
}
|
||||
|
@ -161,7 +153,7 @@ TMX_SetLeap(int leap)
|
|||
return adjtimex(&txc);
|
||||
}
|
||||
|
||||
int TMX_SetSync(int sync)
|
||||
int TMX_SetSync(int sync, double est_error, double max_error)
|
||||
{
|
||||
struct timex txc;
|
||||
|
||||
|
@ -171,8 +163,10 @@ int TMX_SetSync(int sync)
|
|||
status |= STA_UNSYNC;
|
||||
}
|
||||
|
||||
txc.modes = ADJ_STATUS;
|
||||
txc.modes = ADJ_STATUS | ADJ_ESTERROR | ADJ_MAXERROR;
|
||||
txc.status = status;
|
||||
txc.esterror = est_error * 1.0e6;
|
||||
txc.maxerror = max_error * 1.0e6;
|
||||
|
||||
return adjtimex(&txc);
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ int TMX_SetFrequency(double *freq, long tick);
|
|||
int TMX_GetFrequency(double *freq, long *tick);
|
||||
int TMX_ReadCurrentParams(struct tmx_params *params);
|
||||
int TMX_SetLeap(int leap);
|
||||
int TMX_SetSync(int sync);
|
||||
int TMX_SetSync(int sync, double est_error, double max_error);
|
||||
int TMX_TestStepOffset(void);
|
||||
int TMX_ApplyStepOffset(double offset);
|
||||
|
||||
|
|
Loading…
Reference in a new issue