Subject: timer sockets, anyone?
To: None <tech-kern@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-kern
Date: 12/06/2001 20:02:14
I've got something I hacked together for my own interest, and thought
I'd drop a note here in case anyone else is likewise interested.

What I did was to create a new type of socket: timer sockets.  A timer
socket is a socket in address family AF_TIMER.  They are a bit like
routing sockets (AF_ROUTE) in that they do not provide IPC, but rather
communicate with in-kernel facilities.  However, the in-kernel
facilities that timer sockets communicate with are timing, rather than
routing.

The way it works: you socket(AF_TIMER,SOCK_STREAM,0) to create a timer
socket.  Then you use write() (or equivalent, such as writev()) to
write a struct itimerval to it.  This then sets a timer similar to what
setitimer(ITIMER_REAL,...) would set when given the same struct
itimerval, except that rather than delivering SIGALRM, it generates an
information blob on the socket, which you can then read like any other
data available to be read from a socket.

The information blob is presently just a struct defined in an include
file, mostly a struct timeval which is the time at which the event was
generated (as opposed to the time it gets read, which userland can get
in other ways, such as gettimeofday).

Why do this?  Well, I started it as an exercise in adding a new address
family, and it worked splendidly in that respect - but that's a reason
for me to implement it, not for anyone to use it.  Compared to existing
timing facilities, well, there are arguments both ways.  The timing
facilities I know of are setitimer and the use of userland code to
figure out timeout values for select()/poll() based on the current time
and when the next timeout is.

* Can have multiple timer-event streams to a single process without
  conflict; there's only one ITIMER_REAL per process.

* Is input on an fd.  (Depending on how the code is structured and what
  you're doing with the timer events, this can be a positive or a
  negative.  But of course using timer sockets doesn't prevent you from
  also using other, preexisting, facilities.)

* Avoids having to scan timeout lists to figure out select()/poll()
  timeout values; just throw the socket descriptor(s) into the pot.

* Significantly less portable (so far :-).

As always, I'll be happy to correspond on the subject; people who feel
like poking at what I've done are welcome to pick it up from the patch
tree on ftp.netbsd.org (which I've updated):
ftp.netbsd.org:/pub/NetBSD/misc/mouse/patch-tree/.  The bulk of it is
in sys/kern/timer_impl.c, with other pieces in sys/conf/files,
sys/kern/uipc_domain.c, sys/sys/Makefile, and sys/sys/timersock.h.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B