Today I was reading a wonderful albeit older paper by Gene Carlow on the "Architecture of the Space Shuttle Primary Avionics Software System," published in the September 1984 issue of Communications of the ACM. The Shuttle Primary Avionics Software System was developed by IBM; it's remarkable to see how computing has changed since the days of that initial system.
What struck me the most was the author's wonderfully crafted description of the essence of the PASS architecture, in which he notes that "Flight software systems have been characterized by their small size (15k to 30k) and the limited number of functions they perform. Their software architectures reflect a synchronous design approach within which the dispatching of each application process is timed to always occur at a specific point relative to the start of an overall system cycle or loop. A relatively simple streamlined operating system or executive is used, but a lot of care must be taken in the implementation to synchronize the start and completion of the different application processes, and their associated I/O, to prevent overruns at both the process and system levels. A major benefit of this approach is repeatability; however, there is only limited flexibility to accommodate change. Given the increased number and variety of different applications functions that the Shuttle computers are required to perform, and the anticipation that requirements would change as the Shuttle Program evolved, a nonsynchronous approach was adapted for the PASS architecture. Other basic architectural decisions included the isolation of applications processes from the external I/O and computer redundancy management."
The older, synchronous architecture that Gene describes was (and is still) common in a number of hard real-time domains, wherein the main control flow of a system proceeds by dividing time into a number of frames (and subframes) and then carries out processing within those discrete frames. As complexity and computing power increases, a less rigid control flow is desirable, as is manifest in PASS.
This kind of stuff is pretty foreign to the typical Web-centric developer who can (most of the time) happily ignore hard issues of dead lock, live lock, deadly embrace, computing overruns, and starvation, largely because a) delivery times across the public Internet overwhelm the cost of most client-side computations and b) most of this hard stuff is hidden by middleware.