A domain is always in one of only three states: running, available, and waiting.
The picture below is a state diagram for a domain.
Arrows are state transitions, not keys.
Running domains will execute instructions, barring page faults, insufficient CPUs, and a few other temporary obstacles. CPUs are multiplexed among the running domains. Available or waiting domains do not execute instructions.
There are two kinds of gate keys: start keys and resume keys. A start key can deliver a message only when the domain it designates is available. If a running domain tries to invoke a start key to a domain that is not available, the running domain is queued along with other domains invoking start keys to the unavailable domain. They will run again when the designated domain becomes available. A resume key is created as a result of the CALL instruction and is described below.
A program invokes a key by executing one of three invocation instructions, thereby selecting one of three ways to invoke the key: FORK, CALL, or RETURN.
A FORK invocation leaves the invoking domain in the running state.
A CALL leaves the invoking domain in the waiting state and automatically generates within the message, as the last key, a resume key to the invoking domain. The invoking domain remains in the waiting state until the resume key is invoked, whereupon the domain returns to the running state. Resume keys exist only to waiting domains, and as a resume key is invoked, all resume keys to the designated domain disappear and are everywhere efficiently replaced by null keys, q.v.
A RETURN invocation leaves the invoking domain in the available state. If there are domains that were queued by the unavailability of the RETURNing domain, one is promptly run.
The state of the domain is determined solely by the type of invocation, and not by the key being invoked.
Two kinds of gate keys:
Three ways to invoke a key:
Keys that are not gate keys are primary keys, and the response to their invocation is performed by the microkernel. When a primary key is CALLed, usually the microkernel immediately returns a message to the invoker (depending on the nature of the invoked key) in such a way that the invoker cannot determine from the behavior of the key that it is not a start key. Most invocations of primary keys are CALLs. In this case the microkernel needs to “return to” the last key parameter. If the invocation is not a CALL and the last key parameter is a resume key then the message produced by the microkernel will be delivered to the domain designated by the resume key. Otherwise the message is lost.
This style of invocation, together with a matching RETURN invocation of the resume key, plays the role of the classic subroutine linkage and is the primary method of putting software together in KeyKOS. (Domains may share read-write storage for communication, but seldom do.)
The queuing of invokers of a start key to an unavailable domain provides a convenient and efficient queuing mechanism for the domain representing a serially reusable resource. Some services, such as a compiler, have no state between invocations and should be reentrant. In such cases the start key leads to a domain that creates another domain that obeys the compiler for one compilation and then destroys itself. Several compilations may thus proceed at once.
If domain X CALLs a resume key to domain Y the situations of the two domains are thereby reversed:
This action constitutes a co-routine linkage and has the traditional attributes of co-routines.
This is the method typically used by a domain to deliver a sequence of values to another domain, especially when the values are produced or consumed as they are transmitted.
This proceeds until X or Y indicates that it wishes to terminate the relationship, whereupon Y RETURNs to X’s resume key, making Y available for new transactions.
The following functional areas are frequently provided separately in other systems but are bundled in the KeyKOS domain: