Show us where it says that...bob wrote:Sorry, go read up on ntpd. It GUARANTEES that the clock adjustments are applied fractionally so that there is NEVER any step backward. And as it learns how time slips on a specific machine, it gets even better in that it slowly adjusts the clock throughout the day, even between samples.
https://www.ietf.org/rfc/rfc5905.txt
It does not.
Show us where it requires an OS able of adjusting time monotonically.
It does not.
POSIX supports adjtime() which can be used for small monotonic adjustments. Even on a POSIX system the reference implementation in the RFC is not monotonic:
Code: Select all
/*
* step_time() - step system time to given offset value
*/
void
step_time(
double offset /* clock offset */
)
{
struct timeval unix_time;
tstamp ntp_time;
/*
* Convert from double to native format (signed) and add to the
* current time. Note the addition is done in native format to
* avoid overflow or loss of precision.
*/
gettimeofday(&unix_time, NULL);
ntp_time = D2LFP(offset) + U2LFP(unix_time);
unix_time.tv_sec = ntp_time >> 32;
unix_time.tv_usec = (long)(((ntp_time - unix_time.tv_sec) <<
32) / FRAC * 1e6);
settimeofday(&unix_time, NULL);
}
...
/*
* Clock state machine transition function. This is where the
* action is and defines how the system reacts to large time
* and frequency errors. There are two main regimes: when the
* offset exceeds the step threshold and when it does not.
*/
rval = SLEW;
mu = p->t - s.t;
freq = 0;
if (fabs(offset) > STEPT) {
switch (c.state) {
...
default:
/*
* This is the kernel set time function, usually
* implemented by the Unix settimeofday() system
* call.
*/
step_time(offset);
c.count = 0;
s.poll = MINPOLL;
rval = STEP;
if (state == NSET) {
rstclock(FREQ, p->t, 0);
return (rval);
}
break;
}
rstclock(SYNC, p->t, 0);
} else {
/*
* Compute the clock jitter as the RMS of exponentially
* weighted offset differences. This is used by the
* poll-adjust code.
*/
...
And for your convenience, as I realise that reading and somewhat understanding the RFC is too much to ask of you, here is a relevant part:
Code: Select all
11.2.3. Combine Algorithm
...
Each time an update is received from the system peer, the clock
update routine is called. By rule, an update is discarded if its
time of arrival p.t is not strictly later than the last update used
s.t. The labels IGNOR, PANIC, ADJ, and STEP refer to return codes
from the local clock routine described in the next section.
IGNORE means the update has been ignored as an outlier. PANIC means
the offset is greater than the panic threshold PANICT (1000 s) and
SHOULD cause the program to exit with a diagnostic message to the
system log. STEP means the offset is less than the panic threshold,
but greater than the step threshold STEPT (125 ms). In this case,
the clock is stepped to the correct offset, but since this means all
peer data have been invalidated, all associations MUST be reset and
the client begins as at initial start.