Return actual frequency in drv_set_freq functions
This is needed to keep sourcestats accurate when the actual frequency is different from the requested frequency due to clamping (or possibly rounding in future system drivers).
This commit is contained in:
parent
c15db71f9e
commit
1a7415a6ab
10 changed files with 45 additions and 22 deletions
29
local.c
29
local.c
|
@ -394,7 +394,7 @@ LCL_SetAbsoluteFrequency(double afreq_ppm)
|
|||
|
||||
/* Call the system-specific driver for setting the frequency */
|
||||
|
||||
(*drv_set_freq)(afreq_ppm);
|
||||
afreq_ppm = (*drv_set_freq)(afreq_ppm);
|
||||
|
||||
dfreq = (afreq_ppm - current_freq_ppm) / (1.0e6 + current_freq_ppm);
|
||||
|
||||
|
@ -417,6 +417,9 @@ LCL_AccumulateDeltaFrequency(double dfreq)
|
|||
{
|
||||
ChangeListEntry *ptr;
|
||||
struct timeval raw, cooked;
|
||||
double old_freq_ppm;
|
||||
|
||||
old_freq_ppm = current_freq_ppm;
|
||||
|
||||
/* Work out new absolute frequency. Note that absolute frequencies
|
||||
are handled in units of ppm, whereas the 'dfreq' argument is in
|
||||
|
@ -425,7 +428,8 @@ LCL_AccumulateDeltaFrequency(double dfreq)
|
|||
current_freq_ppm = (1.0 + dfreq) * current_freq_ppm + 1.0e6 * dfreq;
|
||||
|
||||
/* Call the system-specific driver for setting the frequency */
|
||||
(*drv_set_freq)(current_freq_ppm);
|
||||
current_freq_ppm = (*drv_set_freq)(current_freq_ppm);
|
||||
dfreq = (current_freq_ppm - old_freq_ppm) / (1.0e6 + old_freq_ppm);
|
||||
|
||||
LCL_ReadRawTime(&raw);
|
||||
LCL_CookTime(&raw, &cooked, NULL);
|
||||
|
@ -510,7 +514,9 @@ LCL_AccumulateFrequencyAndOffset(double dfreq, double doffset)
|
|||
#endif
|
||||
|
||||
/* Call the system-specific driver for setting the frequency */
|
||||
(*drv_set_freq)(current_freq_ppm);
|
||||
current_freq_ppm = (*drv_set_freq)(current_freq_ppm);
|
||||
dfreq = (current_freq_ppm - old_freq_ppm) / (1.0e6 + old_freq_ppm);
|
||||
|
||||
(*drv_accrue_offset)(doffset);
|
||||
|
||||
/* Dispatch to all handlers */
|
||||
|
@ -599,25 +605,30 @@ LCL_SetLeap(int leap)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
void
|
||||
double
|
||||
LCL_SetTempComp(double comp)
|
||||
{
|
||||
double uncomp_freq_ppm;
|
||||
|
||||
if (temp_comp_ppm == comp)
|
||||
return;
|
||||
return comp;
|
||||
|
||||
/* Undo previous compensation */
|
||||
current_freq_ppm = (current_freq_ppm + temp_comp_ppm) /
|
||||
(1.0 - 1.0e-6 * temp_comp_ppm);
|
||||
|
||||
uncomp_freq_ppm = current_freq_ppm;
|
||||
|
||||
/* Apply new compensation */
|
||||
current_freq_ppm = current_freq_ppm * (1.0 - 1.0e-6 * comp) - comp;
|
||||
|
||||
temp_comp_ppm = comp;
|
||||
|
||||
/* Call the system-specific driver for setting the frequency */
|
||||
(*drv_set_freq)(current_freq_ppm);
|
||||
current_freq_ppm = (*drv_set_freq)(current_freq_ppm);
|
||||
|
||||
return;
|
||||
temp_comp_ppm = (uncomp_freq_ppm - current_freq_ppm) /
|
||||
(1.0e-6 * uncomp_freq_ppm + 1.0);
|
||||
|
||||
return temp_comp_ppm;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
6
local.h
6
local.h
|
@ -186,7 +186,9 @@ extern void LCL_SetLeap(int leap);
|
|||
|
||||
/* Routine to set a frequency correction (in ppm) that should be applied
|
||||
to local clock to compensate for temperature changes. A positive
|
||||
argument means that the clock frequency should be increased. */
|
||||
extern void LCL_SetTempComp(double comp);
|
||||
argument means that the clock frequency should be increased. Return the
|
||||
actual compensation (may be different from the requested compensation
|
||||
due to clamping or rounding). */
|
||||
extern double LCL_SetTempComp(double comp);
|
||||
|
||||
#endif /* GOT_LOCAL_H */
|
||||
|
|
5
localp.h
5
localp.h
|
@ -40,8 +40,9 @@ typedef double (*lcl_ReadFrequencyDriver)(void);
|
|||
|
||||
/* System driver to set the current local frequency, in ppm relative
|
||||
to nominal. A positive value indicates that the local clock runs
|
||||
fast when uncompensated. */
|
||||
typedef void (*lcl_SetFrequencyDriver)(double freq_ppm);
|
||||
fast when uncompensated. Return actual frequency (may be different
|
||||
from the requested frequency due to clamping or rounding). */
|
||||
typedef double (*lcl_SetFrequencyDriver)(double freq_ppm);
|
||||
|
||||
/* System driver to accrue an offset. A positive argument means slew
|
||||
the clock forwards. */
|
||||
|
|
|
@ -562,7 +562,7 @@ apply_step_offset(double offset)
|
|||
convention is that this is called with a positive argument if the local
|
||||
clock runs fast when uncompensated. */
|
||||
|
||||
static void
|
||||
static double
|
||||
set_frequency(double freq_ppm)
|
||||
{
|
||||
long required_tick;
|
||||
|
@ -603,7 +603,7 @@ set_frequency(double freq_ppm)
|
|||
required_tick = slewing_tick;
|
||||
}
|
||||
|
||||
if (TMX_SetFrequency(scaled_freq, required_tick) < 0) {
|
||||
if (TMX_SetFrequency(&scaled_freq, required_tick) < 0) {
|
||||
LOG_FATAL(LOGF_SysLinux, "adjtimex failed for set_frequency, freq_ppm=%10.4e scaled_freq=%10.4e required_tick=%ld",
|
||||
freq_ppm, scaled_freq, required_tick);
|
||||
}
|
||||
|
@ -616,6 +616,8 @@ set_frequency(double freq_ppm)
|
|||
current_total_tick;
|
||||
adjust_fast_slew(old_total_tick, old_delta_tick);
|
||||
}
|
||||
|
||||
return dhz * (nominal_tick - current_tick) - scaled_freq / freq_scale;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
|
@ -244,12 +244,14 @@ apply_step_offset(double offset)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
static double
|
||||
set_frequency(double new_freq_ppm)
|
||||
{
|
||||
stop_adjust();
|
||||
current_freq = new_freq_ppm * 1.0e-6;
|
||||
start_adjust();
|
||||
|
||||
return current_freq * 1.0e6;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
|
@ -273,12 +273,14 @@ apply_step_offset(double offset)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
static double
|
||||
set_frequency(double new_freq_ppm)
|
||||
{
|
||||
stop_adjust();
|
||||
current_freq = new_freq_ppm * 1.0e-6;
|
||||
start_adjust();
|
||||
|
||||
return current_freq * 1.0e6;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
|
@ -260,12 +260,14 @@ apply_step_offset(double offset)
|
|||
|
||||
/* ================================================== */
|
||||
|
||||
static void
|
||||
static double
|
||||
set_frequency(double new_freq_ppm)
|
||||
{
|
||||
stop_adjust();
|
||||
current_freq = new_freq_ppm * 1.0e-6;
|
||||
start_adjust();
|
||||
|
||||
return current_freq * 1.0e6;
|
||||
}
|
||||
|
||||
/* ================================================== */
|
||||
|
|
|
@ -54,7 +54,7 @@ read_timeout(void *arg)
|
|||
|
||||
/* Don't allow corrections above 10 ppm */
|
||||
if (fabs(comp) < 10.0) {
|
||||
LCL_SetTempComp(comp);
|
||||
comp = LCL_SetTempComp(comp);
|
||||
|
||||
if (logfileid != -1) {
|
||||
struct timeval now;
|
||||
|
|
|
@ -66,13 +66,14 @@ TMX_ApplyOffset(long *offset)
|
|||
}
|
||||
|
||||
int
|
||||
TMX_SetFrequency(double freq, long tick)
|
||||
TMX_SetFrequency(double *freq, long tick)
|
||||
{
|
||||
struct timex txc;
|
||||
|
||||
txc.modes = ADJ_TICK | ADJ_FREQUENCY | ADJ_STATUS;
|
||||
|
||||
txc.freq = (long)(freq * (double)(1 << SHIFT_USEC));
|
||||
txc.freq = (long)(*freq * (double)(1 << SHIFT_USEC));
|
||||
*freq = txc.freq / (double)(1 << SHIFT_USEC);
|
||||
txc.tick = tick;
|
||||
txc.status = STA_UNSYNC; /* Prevent any of the FLL/PLL stuff coming
|
||||
up */
|
||||
|
|
|
@ -70,7 +70,7 @@ struct tmx_params {
|
|||
|
||||
int TMX_SetTick(long tick);
|
||||
int TMX_ApplyOffset(long *offset);
|
||||
int TMX_SetFrequency(double freq, long tick);
|
||||
int TMX_SetFrequency(double *freq, long tick);
|
||||
int TMX_GetFrequency(double *freq);
|
||||
int TMX_GetOffsetLeftOld(long *offset);
|
||||
int TMX_GetOffsetLeft(long *offset);
|
||||
|
|
Loading…
Reference in a new issue