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:
Miroslav Lichvar 2010-04-20 18:29:39 +02:00
parent c15db71f9e
commit 1a7415a6ab
10 changed files with 45 additions and 22 deletions

29
local.c
View file

@ -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;
}
/* ================================================== */

View file

@ -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 */

View file

@ -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. */

View file

@ -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;
}
/* ================================================== */

View file

@ -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;
}
/* ================================================== */

View file

@ -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;
}
/* ================================================== */

View file

@ -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;
}
/* ================================================== */

View file

@ -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;

View file

@ -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 */

View file

@ -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);