Kernel Application Program Interface
The application program interface (API) is used by the NTP protocol
daemon (or equivalent) to discipline the system clock and set various
parameters necessary for its correct operation. The API is used by
application programs to read the system clock and determine its health
and expected error values. Following is a description of the interface,
as well as the control and monitoring variables involved.
The API consists of two Unix system calls, ntp_gettime() and
ntp_adjtime(). The ntp_gettime() call returns the
current system time in either timespec format in seconds and
microseconds, or timeval format in seconds and nanoseconds, as
determined by a status bit described below. In addition to the time
value, this system call returns variables representing the maximum
credible error and estimated error of the time value in microseconds.
The ntp_adjtime() call is used to set and read certain kernel
state variables according to a number of mode bits set in the call. To
set the variables requires super user permission, but to read them
requires no special permissions. Both system calls return a code
indicating the current status of the system clock; that is, whether a
leap second is pending or whether the clock is synchronized to a working
reference source.
Following is a description of the various values used by the API,
including state variables and control/status bits. Detailed calling
sequences and structure definitions are in the timex.h header
file included in the distribution.
Architecture Constants
The following parameters defined in the timex.h header file
establish the performance envelope of the kernel clock discipline loop.
Included are the current values for these parameters, although they may
be changed in future. Note that changing these values may adversely
affect overflow and rounding behavior and require re-engineering of the
code segments.
- MAXPHASE
MAXFREQ
- Phase errors greater than MAXPHASE (0.5 s) or frequency
errors greater than MAXFREQ (500 PPM) are beyond the range of
the clock discipline algorithm. Values that exceed these limits are
clamped to the limits before being used to discipline the system
clock.
- MINSEC
MAXSEC
- For update intervals less than MINSEC (256 s), the clock
discipline algorithm always operates in PLL mode; while, for update
intervals more than MAXSEC (1024 s), the algorithm always
operates in FLL mode. Between these two limits the mode is selected by
the STA_FLL bit in the status word.
- MAXTC
- The range of time constants supported by the clock discipline
algorithm is limited to the range 0 through MAXTC (10). The
time constant is expressed as a power of two, so that zero corresponds
to one second and 10 corresponds to 1024 s.
Status Word
The various functions of the clock discipline algorithm are
controlled and monitored by the status word. The bits of this word are
read and written using the ntp_adjtime() system call, but super
user privilege is required to write them. The following read/write bits
are defined by the API.
- STA_PLL
- Master enable switch for the PLL/FLL loop. The algorithm is
responsive to time and/or frequency updates if set; otherwise, no change
in the current time or frequency will be made other than to complete a
pending phase adjustment. This bit does not affect the PPS loop.
- STA_PPSFREQ
- Enables the PPS frequency discipline independent of the
STA_PLL bit.
- STA_PPSTIME
- Enables the PPS phase discipline independent of the STA_PLL
bit.
- STA_FLL
- Selects the operating mode when the time constant is in the range 0
through 10. If set, operation is in FLL mode; otherwise, operation is in
PLL mode.
- STA_INS
- STA_DEL
- Controls the system clock behavior in the vicinity of a leap second
insertion or deletion. See the Return Codes and the Leap-Second State
Machine section on this page for how these bits are used.
- STA_UNSYNC
- Set by the synchronization daemon to indicate an unsynchronized or
out-of-tolerance condition, but otherwise has no effect on the clock
discipline algorithm.
- STA_FREQHOLD
- Set by the synchronization daemon to freeze the current frequency
while allowing the phase to be disciplined as usual. This bit is not
used by the NTP Version 4 daemon and is included only for legacy
purposes.
The following read-only status bits are defined by the API.
- STA_PPSSIGNAL
- Indicates the presence of a valid PPS signal. It is set by a valid
PPS update and reset about two minutes during which no signal is
present.
- STA_PPSJITTER
- Indicates a condition of excessive PPS phase jitter. See the
Principles of Operation page for further details.
- STA_PPSWANDER
- Indicates a condition of excessive PPS frequency wander. See the
Principles of Operation page for further details.
- STA_PPSERROR
- Indicates a calibration error in the PPS frequency measurement
algorithm. See the Principles of Operation page for further
details.
- STA_CLOCKERR
- Set by the external clock driver to indicate a fault in the hardware
or driver.
- STA_NANO
- Set to indicate nanosecond mode or reset to indicate microsecond
mode.
- STA_MODE
- Set to indicate FLL mode is in operation or reset to indicate PLL
mode.
- STA_CLK
- Set to indicate the external clock is in use or reset to indicate
the normal kernel clock variable is in use.
Return Codes and the Leap-Second State Machine
Occasionally, it is necessary to adjust the system clock in response
to leap seconds as declared by national standards laboratories. The
adjustments are in integral seconds that may be inserted or deleted in
the local timescale, although no deletion has happened in the past and
is extremely unlikely to happen in the future. The mechanism to
recognize and disseminate the leap events themselves is beyond the scope
of the API.
A leap event is implemented using a state machine in the kernel.
Normally, the machine is in TIME_OK state and nothing special
happens at midnight. In order to arm the machine for the event, the
ntp_adjtime() system call sets the STA_INS or
STA_DEL bit in the status word, which initializes the machine
in either TIME_INS or TIME_DEL state to insert or
delete the second, respectively. If in TIME_INS at second
86,400 of the current day, the machine repeats that second and
transitions to TIME_OOP. One second later it transitions to
TIME_WAIT. If in TIME_DEL at second 86,399 of the
current day, it sets the system clock one second in the future and
transitions to TIME_WAIT. The machine remains in this state
until the STA_INS and STA_DEL bits are both reset in
the status word, after which it transitions to TIME_OK.
It is extremely important to recognize the assumption in this design
that the actual value of the system clock is read by a routine that
always requires the system time to appear a monotonic process; that is,
never runs backward. During the leap second itself, the system clock
will appear to run one unit forward each time it is read, regardless of
its prior value. Once the leap second has expired, the clock will resume
normal operation. This is not a property of the API itself, but rather
an intrinsic property of the system clock reading mechanism.
The current state of the machine is determined by the state word
maintained by the kernel. When no error conditions are in effect, the
value returned by the ntp_gettime() and ntp_adjtime()
system calls is the current value of this word; otherwise, an error
value is returned. Specific reasons for the error can be determined from
the status word returned by the ntp_adjtime() system call. The
following return codes are defined by the API.
- TIME_OK
- No leap second warning is in effect.
- TIME_INS
- A leap second will be inserted following second 86,400 of the
current day.
- TIME_DEL
- A leap second will be deleted following second 86,399 of the current
day.
- TIME_OOP
- A leap second insertion is in progress. Time might not be precisely
coordinated between NTP server sites. This state occurs only during the
actual leap second insertion and lasts for only one second.
- TIME_WAIT
- A leap second insertion has completed.
- TIME_ERROR
- The system clock is currently not synchronized to a reliable server.
This state is declared when one or more of the following conditions are
met.
- STA_UNSYNC or STA_CLOCKERR is set.
- Either the clock is not synchronized to a reliable server or a
failure has occurred in the external clock or clock driver, if
provisioned.
- STA_PPSSIGNAL is reset and either STA_PPSFREQ or
STA_PPSTIME is set).
- The synchronization daemon has requested use of the PPS signal, but
the signal has not been detected during the last two minutes.
- STA_PPSTIME and STA_PPSJITTER are both set.
- The synchronization daemon has requested PPS time discipline, but
the jitter has exceeded the limit.
- STA_PPSFREQ is set and either STA_PPSWANDER or
STA_PPSERROR is set.
- The synchronization daemon has requested PPS frequency discipline,
but either the frequency wander has exceeded the limit or a frequency
measurement has failed due to a glitch.
There are two additional return codes which can be produced by the
kernel. These include the following system-dependent error numbers
defined in the /usr/include/errno.h header file. Note that the
values of these error numbers may collide with the above return codes in
some systems.
- EPERM
- Not super user - attempt to change kernel variables without root
privilege.
- EINVAL
- Invalid argument - attempt to set both MOD_MICRO and
MOD_NANO or MOD_CLKB and MOD_CLKA
simultaneously
Mode Control Bits
The following mode bits specify which kernel values are to be changed
in the ntp_adjtime() system call, as well as the format used
for time values and whether an external clock is selected.
- MOD_OFFSET
- MOD_FREQUENCY
- MOD_MAXERROR
- MOD_ESTERROR
- MOD_STATUS
- MOD_TIMECONST
- MOD_PPSMAX
- These bits control which field of the timex structure are used to
update the corresponding kernel variable. The bits may be set in any
combination. See the description below for which bits control which
variable.
- MOD_NANO
- MOD_MICRO
- These two bits control the scale used in the API interface (but not
the actual operations used by the clock discipline algorithm). Only one
of the two bits should be set. MOD_NANO selects seconds and
nanoseconds (timespec format), while MOD_MICRO selects
seconds and microseconds (timeval format). This applies to both the time
value returned by ntp_gettime() and the offset used by
ntp_adjtime(). Note that not all kernels can support nanosecond
format. The recommended behavior is to select one or the other format
and inspect the STA_NANO bit in the status word to determine
the actual kernel mode. The default when the kernel is first booted is
seconds and microseconds for legacy compatibility.
- MOD_CLKA
- MOD_CLKB
- These two bits control the operation of an external clock, if
present in the architecture. Only one of the two bits should be set.
MOD_CLKB sets the STA_CLK bit in the status word,
while the MOD_CLKA resets it. The behavior in response to the
STA_CLK bit is beyond the scope of the current implementation.
The ntp_adjtime() System Call
The ntp_adjtime() system call is used to set and read kernel
variables used by kernel. It operates using the timex structure
described in the timex.h header file. This structure is used
both to change the values of certain kernel variables and to return the
current values. Root privilege is required to change the values.
Following are the variables that can be read and written. The return
codes are described in the Return Codes and the Leap-Second State
Machine section on this page.
- offset
- If the MOD_OFFSET bit is set in the mode word, this
variable updates the kernel time offset in nanoseconds, if the
STA_NANO bit is set in the status word, or in microseconds if
not.
- freq
- If the MOD_FREQUENCY bit is set in the mode word, this
variable updates the kernel frequency offset in PPM. This is ordinarily
done only when the clock discipline algorithm is first started, since
the frequency is automatically determined by the algorithm after that.
The format of this variable is in PPM with a 16-bit fraction field.
- maxerror
- If the MOD_MAXERROR bit is set in the mode word, this
variable updates the kernel maximum error in microseconds. The error is
automatically updated by the clock discipline algorithm after that and
until the next update. The value is not used for any purpose other than
to provide a conduit from the synchronization daemon to the user
applications.
- esterror
- If the MOD_ESTERROR bit is set in the mode word, this
variable updates the kernel estimated error in microseconds. The value
is not used for any purpose other than to provide a conduit from the
synchronization daemon to the user applications.
- status
- If the MOD_STATUS bit is set in the mode word, this
variable updates the read/write bits in the status word.
- shift
- This variable is actually two variables, one write-only and the
other read-only. When written, the value represents the maximum
calibration cycle length expressed as a power of two, in seconds. When
read, the value represents the current calibration cycle length
expressed as a power of two, in seconds.
The following variables are read-only.
- precision
- Precision of the system clock, in nanoseconds if the
STA_NANO bit is set in the status word, or in microseconds if
not.
- tolerance
- Frequency tolerance of the clock discipline algorithm, in the same
units as the freq variable described above. More precisely,
the maximum clock oscillator frequency error that can be corrected by
the clock discipline algorithm.
The following variables are read-only and present only if the PPS
clock discipline code has been compiled and configured in the kernel.
They are included in the timex structure definition to insure
portability.
- ppsfreq
- Frequency calculated by the PPS loop, in the same units as the
freq variable described above. This calculation is independent
of all other means to adjust the system clock frequency. If enabled by
the API and the PPS signal is within nominals, the clock frequency
should be identical to this value.
- jitter
- Average phase jitter, in nanoseconds if the STA_NANO bit is
set in the status word, or in microseconds if not.
- stabil
- Average wander, in the same units as the freq variable
described above.
- jitcnt
- Count of excess phase jitter occurrences. See the Principles of
Operation page for further details.
- calcnt
- Count of calibration intervals. See the Principles of
Operation page for further details.
- errcnt
- Count of calibration error occurrences. See the Principles of
Operation page for further details.
- errcnt
- Count of excess frequency wander occurrences. See the Principles
of Operation page for further details.
The ntp_gettime() System Call
The ntp_gettime() system call is used to read the current
system time and related error variables. It uses the ntptimeval
structure described in the timex.h header file. This structure
includes the following variables. The return codes are described in the
Return Codes and the Leap-Second State Machine section on this
page.
- time
- Current system clock time, in timespec format if
STA_NANO is set in the status word; in timeval format
if not.
- maxerror
- Maximum credible absolute error of the system clock, in
microseconds. The value is initialized by the ntp_adjtime()
system call and incremented by the kernel after that. The value is not
used for any purpose other than to provide a conduit from the
synchronization daemon to the user applications.
- esterror
- Estimated RMS error of the system clock, in microseconds. The value
is initialized by the ntp_adjtime() system call, but not used
for any purpose other than to provide a conduit from the synchronization
daemon to the user applications.
David L. Mills <mills@udel.edu>