.SH
Select and Non-blocking I/O
.PP
Without select(2), building X would have been very difficult.
It provides the only mechanism in
.UX
for multiplexing many requests
in a single process.
It is essential for the X server to be able to block while testing for work
to do on any client connection and on the keyboard device.
X will then wake up with the information
required to determine which device or connection needs service.
.PP
In actual interactive use of X on a very fast display,
select accounts for both the most CPU time and the most subroutine calls.
Over an afternoon's use on this display, it
accounted for more than 20% of the CPU time used.
This is not surprising, since most use of the window system is generated by
input events going to editors (in our environment), and output
character echoing as well as clock and load monitor graphics calls.
When not loaded, one would expect on the order of one select call
per X request performed.
In fact, there are approximately two X requests performed per select call.
.PP
One should remember that select's overhead diminishes as the load
on the window system increases,
both because you are likely to have many requests on a single connection,
and because multiple connections may be processed on a single call.
Profiling of the server when the display is loaded shows select using
a much smaller percentage of the total CPU time.
.PP
Note that for the typical case under normal use, TWO system calls
will be occurring where one might potentially do.
In the output case (from a client),
X will be blocked in select awaiting input (one call).
It must then read the data from the client and process it (second call).
Due to the shared memory described above, we are avoiding a write system
call to the display.
On input (keyboard or mouse),
X will be blocked in select (one call).
It then gets the input event out of the queue, determines
which client should get the event, and writes it (second call).
Again, we have saved a system call to read the data.
Note that since buffering may occur on both input and output,
the overhead per graphics operation performed will
diminish as the load on the server goes up, since the server
will perform more work for the same amount of overhead.
.PP
Optimally, select should be very cheap.
On fairness grounds, one would like to see if more input from
a different client is available
after each X request.
The original X request handler would check after every request for more
requests.
The current scheduler only checks for more input when all previously read
data has been processed,
and provides an approximately 30% reduction in X server overhead
(all in the select and read system calls).
