Changeset View
Changeset View
Standalone View
Standalone View
head/contrib/ntp/ntpd/ntp_loopfilter.c
Show First 20 Lines • Show All 148 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
int ntp_enable = TRUE; /* clock discipline enabled */ | int ntp_enable = TRUE; /* clock discipline enabled */ | ||||
int pll_control; /* kernel support available */ | int pll_control; /* kernel support available */ | ||||
int kern_enable = TRUE; /* kernel support enabled */ | int kern_enable = TRUE; /* kernel support enabled */ | ||||
int hardpps_enable; /* kernel PPS discipline enabled */ | int hardpps_enable; /* kernel PPS discipline enabled */ | ||||
int ext_enable; /* external clock enabled */ | int ext_enable; /* external clock enabled */ | ||||
int pps_stratum; /* pps stratum */ | int pps_stratum; /* pps stratum */ | ||||
int kernel_status; /* from ntp_adjtime */ | int kernel_status; /* from ntp_adjtime */ | ||||
int allow_panic = FALSE; /* allow panic correction (-g) */ | |||||
int force_step_once = FALSE; /* always step time once at startup (-G) */ | int force_step_once = FALSE; /* always step time once at startup (-G) */ | ||||
int mode_ntpdate = FALSE; /* exit on first clock set (-q) */ | int mode_ntpdate = FALSE; /* exit on first clock set (-q) */ | ||||
int freq_cnt; /* initial frequency clamp */ | int freq_cnt; /* initial frequency clamp */ | ||||
int freq_set; /* initial set frequency switch */ | int freq_set; /* initial set frequency switch */ | ||||
/* | /* | ||||
* Clock state machine variables | * Clock state machine variables | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 288 Lines • ▼ Show 20 Lines | local_clock( | ||||
int rval; /* return code */ | int rval; /* return code */ | ||||
int osys_poll; /* old system poll */ | int osys_poll; /* old system poll */ | ||||
int ntp_adj_ret; /* returned by ntp_adjtime */ | int ntp_adj_ret; /* returned by ntp_adjtime */ | ||||
double mu; /* interval since last update */ | double mu; /* interval since last update */ | ||||
double clock_frequency; /* clock frequency */ | double clock_frequency; /* clock frequency */ | ||||
double dtemp, etemp; /* double temps */ | double dtemp, etemp; /* double temps */ | ||||
char tbuf[80]; /* report buffer */ | char tbuf[80]; /* report buffer */ | ||||
(void)ntp_adj_ret; /* not always used below... */ | |||||
/* | /* | ||||
* If the loop is opened or the NIST LOCKCLOCK is in use, | * If the loop is opened or the NIST LOCKCLOCK is in use, | ||||
* monitor and record the offsets anyway in order to determine | * monitor and record the offsets anyway in order to determine | ||||
* the open-loop response and then go home. | * the open-loop response and then go home. | ||||
*/ | */ | ||||
#ifdef LOCKCLOCK | #ifndef LOCKCLOCK | ||||
if (!ntp_enable) | |||||
#endif /* not LOCKCLOCK */ | |||||
{ | { | ||||
#else | |||||
if (!ntp_enable) { | |||||
#endif /* LOCKCLOCK */ | |||||
record_loop_stats(fp_offset, drift_comp, clock_jitter, | record_loop_stats(fp_offset, drift_comp, clock_jitter, | ||||
clock_stability, sys_poll); | clock_stability, sys_poll); | ||||
return (0); | return (0); | ||||
} | } | ||||
#ifndef LOCKCLOCK | #ifndef LOCKCLOCK | ||||
/* | /* | ||||
* If the clock is way off, panic is declared. The clock_panic | * If the clock is way off, panic is declared. The clock_panic | ||||
* defaults to 1000 s; if set to zero, the panic will never | * defaults to 1000 s; if set to zero, the panic will never | ||||
* occur. The allow_panic defaults to FALSE, so the first panic | * occur. The allow_panic defaults to FALSE, so the first panic | ||||
* will exit. It can be set TRUE by a command line option, in | * will exit. It can be set TRUE by a command line option, in | ||||
* which case the clock will be set anyway and time marches on. | * which case the clock will be set anyway and time marches on. | ||||
* But, allow_panic will be set FALSE when the update is less | * But, allow_panic will be set FALSE when the update is less | ||||
* than the step threshold; so, subsequent panics will exit. | * than the step threshold; so, subsequent panics will exit. | ||||
*/ | */ | ||||
if (fabs(fp_offset) > clock_panic && clock_panic > 0 && | if (fabs(fp_offset) > clock_panic && clock_panic > 0 && | ||||
!allow_panic) { | !allow_panic) { | ||||
snprintf(tbuf, sizeof(tbuf), | snprintf(tbuf, sizeof(tbuf), | ||||
"%+.0f s; set clock manually within %.0f s.", | "%+.0f s; set clock manually within %.0f s.", | ||||
fp_offset, clock_panic); | fp_offset, clock_panic); | ||||
report_event(EVNT_SYSFAULT, NULL, tbuf); | report_event(EVNT_SYSFAULT, NULL, tbuf); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
allow_panic = FALSE; | |||||
/* | /* | ||||
* This section simulates ntpdate. If the offset exceeds the | * This section simulates ntpdate. If the offset exceeds the | ||||
* step threshold (128 ms), step the clock to that time and | * step threshold (128 ms), step the clock to that time and | ||||
* exit. Otherwise, slew the clock to that time and exit. Note | * exit. Otherwise, slew the clock to that time and exit. Note | ||||
* that the slew will persist and eventually complete beyond the | * that the slew will persist and eventually complete beyond the | ||||
* life of this program. Note that while ntpdate is active, the | * life of this program. Note that while ntpdate is active, the | ||||
* terminal does not detach, so the termination message prints | * terminal does not detach, so the termination message prints | ||||
* directly to the terminal. | * directly to the terminal. | ||||
Show All 29 Lines | if (peer->delay < sys_huffpuff[sys_huffptr]) | ||||
sys_huffpuff[sys_huffptr] = peer->delay; | sys_huffpuff[sys_huffptr] = peer->delay; | ||||
if (peer->delay < sys_mindly) | if (peer->delay < sys_mindly) | ||||
sys_mindly = peer->delay; | sys_mindly = peer->delay; | ||||
if (fp_offset > 0) | if (fp_offset > 0) | ||||
dtemp = -(peer->delay - sys_mindly) / 2; | dtemp = -(peer->delay - sys_mindly) / 2; | ||||
else | else | ||||
dtemp = (peer->delay - sys_mindly) / 2; | dtemp = (peer->delay - sys_mindly) / 2; | ||||
fp_offset += dtemp; | fp_offset += dtemp; | ||||
#ifdef DEBUG | DPRINTF(1, ("local_clock: size %d mindly %.6f huffpuff %.6f\n", | ||||
if (debug) | sys_hufflen, sys_mindly, dtemp)); | ||||
printf( | |||||
"local_clock: size %d mindly %.6f huffpuff %.6f\n", | |||||
sys_hufflen, sys_mindly, dtemp); | |||||
#endif | |||||
} | } | ||||
/* | /* | ||||
* Clock state machine transition function which defines how the | * Clock state machine transition function which defines how the | ||||
* system reacts to large phase and frequency excursion. There | * system reacts to large phase and frequency excursion. There | ||||
* are two main regimes: when the offset exceeds the step | * are two main regimes: when the offset exceeds the step | ||||
* threshold (128 ms) and when it does not. Under certain | * threshold (128 ms) and when it does not. Under certain | ||||
* conditions updates are suspended until the stepout theshold | * conditions updates are suspended until the stepout theshold | ||||
▲ Show 20 Lines • Show All 134 Lines • ▼ Show 20 Lines | if ( ( fp_offset > clock_max_fwd && clock_max_fwd > 0) | ||||
/* | /* | ||||
* We get here by default in FSET, SPIK and SYNC states. | * We get here by default in FSET, SPIK and SYNC states. | ||||
* Here compute the frequency update due to PLL and FLL | * Here compute the frequency update due to PLL and FLL | ||||
* contributions. Note, we avoid frequency discipline at | * contributions. Note, we avoid frequency discipline at | ||||
* startup until the initial transient has subsided. | * startup until the initial transient has subsided. | ||||
*/ | */ | ||||
default: | default: | ||||
allow_panic = FALSE; | |||||
if (freq_cnt == 0) { | if (freq_cnt == 0) { | ||||
/* | /* | ||||
* The FLL and PLL frequency gain constants | * The FLL and PLL frequency gain constants | ||||
* depend on the time constant and Allan | * depend on the time constant and Allan | ||||
* intercept. The PLL is always used, but | * intercept. The PLL is always used, but | ||||
* becomes ineffective above the Allan intercept | * becomes ineffective above the Allan intercept | ||||
* where the FLL becomes effective. | * where the FLL becomes effective. | ||||
▲ Show 20 Lines • Show All 210 Lines • ▼ Show 20 Lines | #endif /* KERNEL_PLL */ | ||||
if (osys_poll != sys_poll) | if (osys_poll != sys_poll) | ||||
poll_update(peer, sys_poll); | poll_update(peer, sys_poll); | ||||
/* | /* | ||||
* Yibbidy, yibbbidy, yibbidy; that'h all folks. | * Yibbidy, yibbbidy, yibbidy; that'h all folks. | ||||
*/ | */ | ||||
record_loop_stats(clock_offset, drift_comp, clock_jitter, | record_loop_stats(clock_offset, drift_comp, clock_jitter, | ||||
clock_stability, sys_poll); | clock_stability, sys_poll); | ||||
#ifdef DEBUG | DPRINTF(1, ("local_clock: offset %.9f jit %.9f freq %.3f stab %.3f poll %d\n", | ||||
if (debug) | |||||
printf( | |||||
"local_clock: offset %.9f jit %.9f freq %.3f stab %.3f poll %d\n", | |||||
clock_offset, clock_jitter, drift_comp * 1e6, | clock_offset, clock_jitter, drift_comp * 1e6, | ||||
clock_stability * 1e6, sys_poll); | clock_stability * 1e6, sys_poll)); | ||||
#endif /* DEBUG */ | |||||
return (rval); | return (rval); | ||||
#endif /* LOCKCLOCK */ | #endif /* not LOCKCLOCK */ | ||||
} | } | ||||
/* | /* | ||||
* adj_host_clock - Called once every second to update the local clock. | * adj_host_clock - Called once every second to update the local clock. | ||||
* | * | ||||
* LOCKCLOCK: The only thing this routine does is increment the | * LOCKCLOCK: The only thing this routine does is increment the | ||||
* sys_rootdisp variable. | * sys_rootdisp variable. | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | #endif /* KERNEL_PLL */ | ||||
clock_offset -= offset_adj; | clock_offset -= offset_adj; | ||||
/* | /* | ||||
* Windows port adj_systime() must be called each second, | * Windows port adj_systime() must be called each second, | ||||
* even if the argument is zero, to ease emulation of | * even if the argument is zero, to ease emulation of | ||||
* adjtime() using Windows' slew API which controls the rate | * adjtime() using Windows' slew API which controls the rate | ||||
* but does not automatically stop slewing when an offset | * but does not automatically stop slewing when an offset | ||||
* has decayed to zero. | * has decayed to zero. | ||||
*/ | */ | ||||
DEBUG_INSIST(enable_panic_check == TRUE); | |||||
enable_panic_check = FALSE; | |||||
adj_systime(offset_adj + freq_adj); | adj_systime(offset_adj + freq_adj); | ||||
enable_panic_check = TRUE; | |||||
#endif /* LOCKCLOCK */ | #endif /* LOCKCLOCK */ | ||||
} | } | ||||
/* | /* | ||||
* Clock state machine. Enter new state and set state variables. | * Clock state machine. Enter new state and set state variables. | ||||
*/ | */ | ||||
static void | static void | ||||
rstclock( | rstclock( | ||||
int trans, /* new state */ | int trans, /* new state */ | ||||
double offset /* new offset */ | double offset /* new offset */ | ||||
) | ) | ||||
{ | { | ||||
#ifdef DEBUG | DPRINTF(2, ("rstclock: mu %lu state %d poll %d count %d\n", | ||||
if (debug > 1) | |||||
printf("local_clock: mu %lu state %d poll %d count %d\n", | |||||
current_time - clock_epoch, trans, sys_poll, | current_time - clock_epoch, trans, sys_poll, | ||||
tc_counter); | tc_counter)); | ||||
#endif | |||||
if (trans != state && trans != EVNT_FSET) | if (trans != state && trans != EVNT_FSET) | ||||
report_event(trans, NULL, NULL); | report_event(trans, NULL, NULL); | ||||
state = trans; | state = trans; | ||||
last_offset = clock_offset = offset; | last_offset = clock_offset = offset; | ||||
clock_epoch = current_time; | clock_epoch = current_time; | ||||
} | } | ||||
Show All 34 Lines | |||||
static void | static void | ||||
set_freq( | set_freq( | ||||
double freq /* frequency update */ | double freq /* frequency update */ | ||||
) | ) | ||||
{ | { | ||||
const char * loop_desc; | const char * loop_desc; | ||||
int ntp_adj_ret; | int ntp_adj_ret; | ||||
(void)ntp_adj_ret; /* not always used below... */ | |||||
drift_comp = freq; | drift_comp = freq; | ||||
loop_desc = "ntpd"; | loop_desc = "ntpd"; | ||||
#ifdef KERNEL_PLL | #ifdef KERNEL_PLL | ||||
if (pll_control) { | if (pll_control) { | ||||
ZERO(ntv); | ZERO(ntv); | ||||
ntv.modes = MOD_FREQUENCY; | ntv.modes = MOD_FREQUENCY; | ||||
if (kern_enable) { | if (kern_enable) { | ||||
loop_desc = "kernel"; | loop_desc = "kernel"; | ||||
▲ Show 20 Lines • Show All 145 Lines • ▼ Show 20 Lines | |||||
loop_config( | loop_config( | ||||
int item, | int item, | ||||
double freq | double freq | ||||
) | ) | ||||
{ | { | ||||
int i; | int i; | ||||
double ftemp; | double ftemp; | ||||
#ifdef DEBUG | DPRINTF(2, ("loop_config: item %d freq %f\n", item, freq)); | ||||
if (debug > 1) | |||||
printf("loop_config: item %d freq %f\n", item, freq); | |||||
#endif | |||||
switch (item) { | switch (item) { | ||||
/* | /* | ||||
* We first assume the kernel supports the ntp_adjtime() | * We first assume the kernel supports the ntp_adjtime() | ||||
* syscall. If that syscall works, initialize the kernel time | * syscall. If that syscall works, initialize the kernel time | ||||
* variables. Otherwise, continue leaving no harm behind. | * variables. Otherwise, continue leaving no harm behind. | ||||
*/ | */ | ||||
case LOOP_DRIFTINIT: | case LOOP_DRIFTINIT: | ||||
▲ Show 20 Lines • Show All 141 Lines • Show Last 20 Lines |