The Horus system is implemented over the
MUTS (Multi-threading and
Unreliable Transport Service) kernel (a scaled down version
of an earlier system we developed called MUTS).
MUTS
provides prioritized multi-threading and a collection of drivers for
different network interfaces such as UDP sockets, the MACH ATM interface,
and the x-kernel interface.
MUTS contains a sophisticated message
interface that avoids copying, even when crossing address spaces.
MUTS also manages how memory is divided among the modules of an
application, in an attempt to deal with scarce memory situations while
avoiding deadlock.
Using the services of
MUTS,
each Horus layer implements the interface of tables 1
and 2.
The interface names are made unique for linking purposes. A separate
dispatch table per layer is used to implement interface overloading.
Although Horus supports C++ programs, it is implemented in C for
maximum portability and performance.
A process can specify at run-time, at each layer, how it wants upcalls to be invoked. This allows for maximum performance and ease of use. We currently support three types of upcall dispatch: thread creation, procedure invocation, and message enqueuing. Horus numbers all events, hence in the threaded case, concurrently active threads can synchronize themselves in event delivery order by using the Horus event number as the input to an event count synchronization barrier [10]. Such a barrier creates a mutual exclusion region that threads can only enter in sequential order.
As noted earlier, most applications use Horus through a socket interface.
This is implemented by a
socket layer that intercepts UNIX system calls, reimplementing them so
that Horus can run multiple threads and support group communication
sockets. It also allows multiple subsystems to co-exists in the same
UNIX process. For example, one thread can run X Windows client code,
while another thread deals with group communication.
MUTS supports
special file descriptors that can be used for safe interaction between
the threads.