Previous Table of Contents Next


This structured approach works well, as evidenced by the number of successful Unix operating systems in use today. It is, however, difficult to add features or change existing features using this approach, because of its monolithic design. The entire operating system is bound together in the hierarchy of layers. It is not easy to pull out one layer and replace it with a new layer, because the interfaces between layers are many and varied. An intimate knowledge of the operating system and lots of time are usually required to make changes to any of these layers. In addition, many of the APIs between layers are undocumented, making it even more difficult to guarantee code correctness when a change is made. This is a real problem when new functions need to be added or moved from one layer to another.

A microkernel replaces this vertical communication hierarchy with a horizontal structure. All operating-system components above the microkernel communicate directly with one another, using messages that pass through the microkernel. The microkernel validates the messages, passes them between components, and grants access to the hardware resources. An operating system designed around a microkernel is very extensible. Operating-system components become quite modular with this design. New components, which were never even envisioned when the operating system was created, can be plugged in without tearing up other parts of the design.

But there is a cost for all of this. Message passing is not as fast as the function calls a typical Unix system uses, so care must be taken to optimize the performance of message passing in the microkernel. But even though message passing is not as fast as a function call, it still can improve system performance if it eliminates the need to go through unnecessary levels.

Thus far, everything we have said about communications in a microkernel design applies to the AS/400. The tasking structure of both the System/38 and the AS/400 is message-based, exactly like that of the microkernel. OS/400 users are familiar with messages. Application and operating-system components in the AS/400 communicate using messages, and all work in the system is dispatched as a result of these communications. As with the implementation of a microkernel, the AS/400’s tasking structure is implemented at the lowest level of the system. In the System/38 and the early AS/400, tasking was implemented in the HLIC. But in the RISC-based AS/400 systems, tasking is implemented in the SLIC for optimal performance. SLIC is not a microkernel, nor is it built on a microkernel. It does, however, share many of the same design philosophies.

Microkernels got their start in the mid-1980s, when Carnegie Mellon University developed the Mach microkernel. In recent years, many new operating systems, such as Windows NT, are based on a microkernel model. Although there is far more to a microkernel than just the message-based communications and dispatching mechanism, it is important to note that this mechanism, which all these new operating systems use, was pioneered in the System/38 and later used in the AS/400. For this reason, we want to start our study of process management at the bottom of the AS/400 system.

Starting at the Bottom

Earlier, we defined a process and said it was basically a unit of work in the system. A task is also a unit of work in the system, so in this respect a task is similar to a process. A process is a higher-level function in SLIC that is built on top of a task. There is a third, even higher-level, unit of work in OS/400, called a job. We will see how these three concepts of work on an AS/400 interrelate.

The names task and process came from two different System/38 development organizations. Engineering talked about tasks, and programming talked about processes. Many people thought that because of the different names, there must be fundamental differences between the two, but there were not.

In the early days of the System/38 development, we were trying to define the mechanism the operating system would use to control the flow of work and the allocation of resources within the system. This, after all, is the primary responsibility of any operating system, and we wanted to make sure we got it right. Operating systems in the early 1970s were just starting to incorporate the idea of a process as a unit of work in the system. We, too, thought this was a good idea for our operating system.

The processors in those days knew nothing about a process. They had evolved during the 1960s, but they understood only interrupts. An interrupt is a change in the flow of instruction execution caused by either an error detected while executing an instruction or something outside the running program. This latter cause is usually related to I/O. The processor initiates the I/O device operations, which then execute outside the processor. When an I/O operation completes, it needs some way to tell the processor, and an interrupt provides that mechanism.

An interrupt stops the running program and transfers control to an interrupt handler, which performs some appropriate action. When the interrupt handler finishes, it returns control to the interrupted program. The interrupt handler must restart the interrupted program in exactly the same state it was in when the interrupt occurred. This means restoring all the internal registers to their pre-interrupt state. Some processors provide multiple sets of registers, and when an interrupt occurs, the interrupt handler uses a different set of registers. Returning control to the interrupted program means switching back to the original set of registers.

Most interrupt schemes include the idea of priority. Priority provides a pecking order for interrupts, from most important to least important. When an interrupt occurs, the processor is switched to a new program only if that program has a higher priority than the running program. Most processors provide only a small number of interrupt priorities. To support processes, the operating-system software must take the interrupt mechanism and build processes on top.

In the 1970s, we were building a new microprogrammed processor for the System/38. We reasoned that if we could build a process structure right on top of the hardware, and eliminate some of the interrupt overhead, we would have a more efficient system. Even our I/O could use this process structure, without the need for a separate interrupt mechanism. This would also save circuits in the processor — something near and dear to engineering management.

In effect, engineering had signed up to create the process structure for the system and to write the microcode to support it. But explaining what we were doing to someone in engineering proved to be an interesting experience.


Previous Table of Contents Next

Copyright © NEWS/400 Books