Background


Nemesis is (also) an experimental operating system, built from the ground up to support Quality of Service (QoS) guarantees in multimedia applications. Originally developed at the Computer Lab at Cambridge University, with later contributions from University of Glasgow (Scotland), University of Twente (Netherlands) and the Swedish Institute of Computer Science.

Goals for the Operating System include not only providing the necessary support for real-time and multimedia applications, but also the provision of a stable and flexible (and largely Open Source) platform for practical research in multimedia and QoS, particularly Network QoS (largely ATM based) and Disk QoS projects at Cambridge.
 
 

What is QoS?


Quality of Service, as a general concept in computing, is more or less what you'd expect from the name. A Quality of Service guarantee states that resources necessary to complete or maintain a process are guaranteed to be available within a specified timescale, and can be applied to almost any resource available in a computer system:

For example, to play a RealVideo movie might require 56kbps of network bandwidth, some buffering in physical memory, and a small amount of CPU time for each frame. If one of these isn't available at the correct time, frames will be dropped and the movie will lose quality.

In a traditional operating system, scheduling of resource allocation to a process is based on a simple prioritized time-sharing system, typically with the CPU scheduling demand-driving other resource allocation (such as physical memory). The availability of resources to a program therefore depends on the activity of other programs on the system. In the above example, where the movie needs 56kbps of network bandwidth, the movie's playback would be affected by some other application (e.g.. NewsUpd) requiring network bandwidth, particularly if the connection was via a 56kbps.

This unintentional interaction between different applications clamoring for resources is known as crosstalk.

You're probably already familiar with these effects if you've ever tried to use your computer while watching a DVD or burning a CDR. The cross-talk across your CPU usage or disk access will adversely affect the behaviour of the DVD player or CD burner. In the former the result is annoying; in the latter, you get coasters.

Nemesis schedules resources (primarily CPU time) by allocating a guaranteed portion of a resource to a process, and ensuring that it's always available.  The DVD player application above would be allocated it's required CPU time, and regardless of the activities of other CPU-intensive applications, the required CPU would always be available to the DVD player, allowing continuous glitch-free operation. If the operating system had already committed too much CPU time and couldn't allocate the necessary time to play the DVD properly, it would warn about this, rather than making a half-assed job of it and at the same time disrupt the operation of other processes.

It seems obvious, doesn't it?
 
 

Technical Details


Fundamentally, Nemesis is a microkernel operating system, consisting of a small supervisor mode executable (the NTSC, or the Nemesis Trusted Supervisor Code) managing direct access to hardware and driving processor scheduling etc. Since there's a fairly small amount of architecture specific code, ports exist for i386 PC hardware, Alpha platforms and various ARM platforms including RiscPC and Sidewinder.

All other functionality is provided by various layers of code libraries. Process model, file systems, network protocols etc. are implemented by libraries. Even applications are fundamentally libraries.

This greatly helps in accounting for CPU usage by an application. under UNIX and X-Windows, a video player process uses some CPU time to decode it's data, but also requires some CPU time in the X server process to render that data to the framebuffer. The necessary CPU time to play the video can't be accounted for simply as the CPU time used by the video player process: it also includes the time used by the X server on behalf of the video player. This is difficult to extract from the time used by the X server since it will also include time used on behalf of other applications. Nemesis' library based approach allows the entire activity to be carried out (excluding window control functions which are still handled by a single server application...) by the process itself. The precise amount of CPU time needed can be calculated and guaranteed to that process.

Nemesis is also a Single Address Space operating system. An object in memory will live at the same address visible to every application. This reduces context switching overhead by cutting down on the memory mapping required to move from one process to another, and on systems (such as ARM systems) which have virtually mapped caches, it eliminates the need to flush the caches on each context switch, allowing higher resolution scheduling in small chunks of time. This isn't to say that memory protection is absent; applications are protected from each other, but only the protection permissions are changed on a context switch. Other applications' data is still mapped into memory, but inaccessible unless explicitly shared.

This single address space raises all sorts of problems: A library may be used by more than one program at the same time. Data local to that library cannot be stored at a fixed address since multiple instances of the data must be kept. All libraries must know to keep their data at an address specific to the calling application. Global state in Nemesis is truly global. Since application programs are also libraries (and can be invoked as multiple processes), most C programs which rely on global state will not run without modification.

This has been the primary barrier to Nemesis' development as a useful platform, but has been overcome with the use of such tools as pre-processors which move 'static' state to structs referenced by a local pointer.

Libraries in Nemesis export their interfaces as a closure, in the CLU sense of the word: an interface encapsulating some state and functions (much like a class in C++, but without all the messy vtables). These interfaces are defined and compiled to C from an abstract Ada-like language, much like Mach's interfaces.

Nemesis has a CLU-like scripting language, known as Clanger, which allows libraries to be scripted, and the global namespace manipulated. More importantly, however, it allows Nemesis types to say "Yes, I do speak Clanger..." :-)
 

Far more information than you could ever possibly want to know is available from the Nemesis homepage at the Computer Lab:

http://www.cl.cam.ac.uk/Research/SRG/netos/old-projects/nemesis/