Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 07 Apr 1996 17:40:49 -0400
From:      "Louis A. Mamakos" <louie@TransSys.COM>
To:        Terry Lambert <terry@lambert.org>
Cc:        msmith@atrad.adelaide.edu.au, roell@blah.a.isar.de, hackers@FreeBSD.ORG, jkh@time.cdrom.com, roell@xinside.com
Subject:   Re: The F_SETOWN problem.. 
Message-ID:  <199604072140.RAA00753@whizzo.transsys.com>
In-Reply-To: Your message of "Sun, 07 Apr 1996 12:39:52 PDT." <199604071939.MAA00383@phaeton.artisoft.com> 

next in thread | previous in thread | raw e-mail | index | archive | help

> > While not an X server application, you'll note that xntpd uses SIGIO
> > so that it might read and, most importanty, timestamp traffic arriving
> > on the network.  This is critical to making NTP accurately synchronize
> > the clock.  By using SIGIO, you can not have to worry nearly so much
> > about long-running sections of code and not being able to check for
> > pending input for a "long" time.  The model of signal as 'interrupt'
> > works extremely well for this sort of appliation.  Of course, this all
> > works Just Fine with sockets..
> 
> Signals are not events.  What is wrong with select() that makes it
> unsuitable for your use?

Right, Berkeley/POSIX signals are more interrupts than actual events.
It's an indication that "something" interesting has just happened,
which fits some applications rather nicely.

I'll describe the way that SIGIO is used inside the xntpd daemon
process.  If you're not familiar with the way that the protocol
machinary in NTP works, it relies on periodically exchanging packets
with peers on the network.  The peers poll each other starting at
every 64 seconds, which ramps up to as much as every 512 (or more)
seconds if the path has a low dispersion.

These packets contain, among other things, a set of 64 bit timestamps
which are used in a computation to derive the relative clock offset
and round-trip delay time to a peer.  There is also quite a suite of
sophisticated filtering and clock selection algorithms which are used
to select or discard individual clock offset/delay samples.

A critical part of all this which directly affects the overall
precision and accuracy to which you can synchronize the frequency and
phase of your clock is the ability to promptly timestamp the arrival
time of an NTP packet as it arrives from a peer.  This timestamp is
used as part of the computation to determine an offset and delay
sample. 

Packets being transmitted are rarely an issue, as they are timestamped
and then pretty much synchronously sent on the wire as a result of the
send() system call.  

Now, the xntpd daemon might be in the midst of performing some
computationally expensive process, and may not be 'idle' for hunderds
of microseconds or even a few milliseconds.  It may be, for example,
in the middle of performing a cryptographic algorithm to authenticate
the source of the frame, which in NTP is either a DES based crypto
digest or more recently, an MD5 based digest which I contributed some
years ago.  Or if you have a large number of peers, it may still be
running the peer selection algorithm.  Or a median filter algorithm to
accept or ignore a received offset/delay sample.  Or something so
mundane as printf.

What a SIGIO based scheme does is interrupt whatever computation is
going on, read the packet from the socket, timestamp it, and put it
into a queue to be processed at some later time.  Once you've noted
the arrive time, the time criticality is gone, and you can process it
at your leisure.

>From what I can see, there are four alternatives to the SIGIO scheme:

- multiple priority threads within the process, with the network I/O
thread having higher priority.  We don't typically have real threads
available on most BSD systems.  It would be interesting to see how
well this might work on more recent Sun operating systems.

- OS support for timestamps.  I prototyped this in the original ntp3.4
code that Mike Petry and myself worked on, with a modification to the
socket code in a 4.3BSD-tahoe (I think?) kernel.  This involved a
socket option and using recvmsg() to read the data and associated
'control' information which included a timestamp.  This worked pretty
well.

- A whole seperate process doing this synchronously, talking to a
master xntpd process using pipes or some other horror.  Ick.

- Dropping a whole bunch of subroutine calls throughout the code to
poll for input via a non-blocking select.  Ick, again.

Logically, an external, serially attached reference clock (like a
Rhubidium clock, GPS-synced clock, WWVB-synced clock, or LORAN-synced
clock) can be modeled pretty much exactly like a stratum-1 NTP peer in
the code and are handled in much the same way.  This is why you see
mondo-bizzaro line disclipline code to support timestamping the
arrival of characters or preferably, RS232 control signal state
changes which are connected to a 1 pulse-per-second signal from the
clock.

> So it's not like you get increased response time or anything.

Response time isn't really the problem so much as precision in marking
an event, such as packet arrival.  If you pay reasonable care to all
this, you can get the phase (that is, offset) of the local clock to
within single digits of milliseconds over a somewhat reasonable
quality network path, like an local ethernet.  Heck, you can even tell
the temperature of the room your computer is in by calibrating the
frequency offset of the computer's clock based on the effect the
temperature has on the crystal oscillator.

Of course, some of us are really weird this way.  That how we end up
with PLL models of the computer's clock in the kernel.

louie




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199604072140.RAA00753>