Vanguard (microkernel)
From Wikipedia, the free encyclopedia
Vanguard was an experimental microkernel developed at Apple Computer in the early 1990s. Based on the V-System, Vanguard introduced standardized object identifiers and a unique "message chaining" system for improved performance. Vanguard was not used in any of Apple's commercial products, and development ended in 1997 when Apple's research group (ATG) was dismantled.
Contents |
[edit] Basic concepts
Vanguard was generally very similar to the V-System, but added support for true object oriented programming of the operating system. This meant that kernel and server interfaces were exported as objects, which could be inherited and extended in new code. This change has no real effect on the system itself, it is primarily a change in the source code that makes programming easier.
For instance, Vanguard had an I/O class which was supported by a number of different servers, networking and file servers for instance, which new applications could interact with by importing the I/O interface and calling methods. This also made writing new servers much easier, both because they had a standard to program to, as well as being able to share code more easily.
[edit] V messaging semantics
A key concept to almost all microkernels is breaking down a single large kernel into a set of communicating servers. Instead of having a single large program in control of the entire hardware side of the computer system, these sorts of duties are handed out to smaller programs that are given rights to control different parts of the machine. For instance, a particular server might be given control of the networking hardware, while another has the task of managing the hard drives. Another server would handle the file system, calling both of these lower-level servers. User applications ask for services by sending messages to these servers, using some form of inter-process communications (IPC), as opposed to asking the kernel to do this work via a syscall or trap.
Under V the IPC system appears to be conceptually modeled on remote procedure calls (RPC) from the client application's perspective. The model is slightly different as seen from the server's perspective, as all messages normally arrive at a single thread. For simple requests the server could then immediately hand back a response, but for requests that might take some time, it had the option of spawning off a new worker thread as required. When the server completed processing the results were handed back, and the client given control of the system once again. The server then went into a "receive mode" awaiting further requests.
V's model was very different than most microkernel systems, which used a model based on I/O for message passing. For instance, Mach (where many of these ideas originated) used the I/O system to send messages as if they were (essentially) network traffic. The normal operation of a Unix kernel is to switch out of any application waiting on I/O, so a side effect of sending data and waiting for a response would be to pause the client. But, unlike the RPC model of V, under Mach the entire Unix-like scheduler system would then be called on to select the next application to run. This might result in the server being called, but it might not be. Not only does this mean that clients might wait an indefinite time for responses, but it also means that the messaging system itself is very heavyweight as the scheduler runs every time. Under the V-System model the message passing overhead is reduced because the process scheduler does not have to be consulted, there is no question as to who should next be run – the server being called. The downside to the V approach is that it requires more work on the server side if the response may take some time to process.
[edit] Chaining
One major addition to the IPC system under Vanguard, as opposed to V, was the concept of message chains, allowing a single message to be sent between several interacting servers in a single round-trip. In theory, chaining could dramtically improve the performance of common multi-step operations.
Consider the case where a client application wishes to read a file. Normally this would require one message to the kernel to find the file server, then three messages to the file server, one to resolve the file name into an object id, another to open that id, then finally another to read the file. With chaining a single message could be constructed by the client that contained all of these requests. The message would be sent to the kernel, and then passed off to the file server who would handle all three requests before finally returning data.
Much of the performance problem normally associated with microkernel systems are due to the context switches as messages are passed back and forth between applications. In the example above running on a V system there would be a total of eight context switches, two for each request as the client was switched to and from. Using a chain in Vanguard this would be reduced to only three switches, one out of the client into the kernel, another from the kernel to the file server, and finally from the server back to the client. In some cases the overhead of a context switch is greater than the time it takes to actually run the request, so Vanguard's chaining mechanism could result in real-world performance improvements.
[edit] Object naming
V had also introduced a simple distributed name service. The name service stored "well known" character names representing various objects in a distributed V system, for instance "2nd floor laser printer". Applications could ask the name server for objects by name, and would be handed back an identifier that would allow them to interact with that object. The service was not a server, that is, it was not an application on its own and was managed by code in the kernel itself. Contrast this with the full-blown name server under the Spring operating system, which not only knew about objects inside the system, but was also used by other servers on the system to translate their private names – file names and IP addresses for instance.
Under the V-System, objects in servers were referred to via an ad-hoc private key of some sort, say a 32-bit integer. Clients would pass these keys into the servers in order to maintain a conversation about a specific task. For instance, an application might ask the kernel for the "file system" and be handed a 32-bit key representing a program, and then use that key to send a message to the file system asking it to open the file "my addresses", which would result in a 64-bit key being handed back. The keys in this example are both internal to the servers in question, there was no common key format.
This sort of conversation was so common under V that the authors decided to make these keys first-class citizens under Vanguard. Instead of using whatever object ID's the servers just happened to use, under Vanguard all servers were expected to understand and return a globally unique 128-bit key, the first 64-bits containing a server identifier, the second identifying an object in that server. The server id was maintained in the kernel, allowing it to hand off the message over the network if the server being referenced was on a remote machine. To the client this was invisible. It is not clear if the id's were handed out randomly to avoid "guessing" by ill-intentioned software.