The Master Control Program (MCP) was the operating system of the B5000 and its successors (the Bnm00 series, A Series of the 1980s, to today's Unisys ClearPath machines). Originally written in ESPOL (Executive Systems Programming Language), which itself was an extension of Burroughs Extended ALGOL, it was converted to NEWP, which was basically a better structured and more secure form of ESPOL in the 1970s.
The MCP's role is to manage the resources of a system, providing controlled access to those resources (security) and to provide common services for programs running on that system.
The MCP started life as about 30,000 lines of code. Over thirty years, this has grown to several million lines (compare that to less-sophisticated systems which are implemented in 100s of millions of lines of C with hundreds of programmers to the less than 100 who work on MCP). The MCP is also updated on a yearly basis, providing customers with a smooth transition (compare that to popular C-based operating systems, which force customers into huge jumps often requiring the purchase of completely new hardware). Updating system software is also very easy and a complete OS update can be done in just half an hour with even less downtime for just the restart. Many system components can be replaced on the fly (see under libraries).
In 1961, the MCP was the first OS written exclusively in a high-level language (HLL) and it probably still is the only OS written exclusively in an HLL, since other systems use assembler for small parts. It is widely believed that Unix was the first system written in an HLL, C, but this was about eight years after the MCP and C is a low-level language when compared to the ALGOL dialects used in the B5000. The hardware features of the B5000 were also designed in tandem with software considerations – a unique and innovative approach in 1961, and still quite unique today.
The MCP was also the first OS whose sourcecode could be scrutinized by the interested public, this being enabled by the readability of the high-level code (although the source is proprietary). This allowed customers to provide their own extensions to the OS and other parts of the system software suite. Many such extensions have found their way into the base OS code over the years and provided to all customers – just as with today's open-source projects.
The MCP was the first commercial OS to provide virtual memory and this was supported by the B5000 hardware (for a description of how the virtual memory works, see the B5000 entry).
Unlike other mainframe systems, MCP provides an online interactive user experience, in contrast to the mainly batch environments of other mainframes with online facilties built on top (although MCP can handle batch processing perfectly well).
The MCP provides a sophisticated file system with hierarchical directory structures. Unlike Unix though, directory nodes are not represented by separate files with directory entries, but rather a 'FLAT' directory listing all file paths on a volume. This is because opening files by visiting and opening each directory in a file path was inefficient and for a production environment it was found to be better to keep all files in a single directory, even though they retain the hierarchical naming scheme. Programmatically, this makes no difference.
FIles are stored on named volumes, for example 'this/is/a/filename on myvol', 'myvol' being the volume name. This is device independent, since the disk containing 'myvol' can be moved or copied to different physical disk drives. This is better than file systems where physical device names must be used to access files, for example 'a:', 'b:', 'c:', etc. Thus files are location independent and since drives can be moved around, this gives a form of plug-and-play. Often system files are loaded on a volume called 'DISK' for system files that don't change, and running system data, such as the virtual memory file, system logs, etc on a volume called 'PACK'. However, these names are not mandatory.
Disks can also be concatenated so that a single volume can be installed across several drives, as well as mirrored for recoverability of sensitive data.
Each file in the system has a set of file attributes. These record all sorts of meta information about a file, most importantly its name and its type (which tells the system how to handle a file, like on the Macintosh). Other attributes have the files record size (if fixed for commercial applications), the block size (in multiples of records which tells the MCP how many records to read and write in a single physical IO) and an area size in multiples of blocks, which gives the size of disk areas to be allocated as the file expands.
The file type indicates if the file is character data, or source code written in particular languages, binary data, or code files.
Files are protected by the usual security access mechanisms such as public or private, or a file may have a guard file where the owner can specify complex security rules.
Another security mechanism is that code files can only be created by trusted compilers. Malicious programmers cannot create a program and call it a compiler – a program could only be converted to be a compiler by an operator with sufficient privileges with the 'mc' make compiler operator command.
The MCP manages processes by scheduling tasks. Running processes are those which are using a processor resource and are marked as 'running'. Processes which are ready to be assigned to a processor, when there is no free processor are placed in the ready queue. Processes may be assigned a priority, generally 50 as the default, but from 1 to 80 for user processes. System processes may be assigned higher values.
Processes which are waiting on other resources, such as a file read wait on the EVENT data structure. Thus all processes waiting on a single resource wait on a single event. When the resource becomes available, the event is caused, which wakes up all the processes waiting on it. Processes may wait on multiple events for any one of them to happen, including a time out. Events are fully user programmable – that is users can write systems that use the generalized event system provided by the MCP.
Processes that have terminated are marked as completed.
Operationally, the status of all tasks in the system is displayed to the operator. All running and ready processes are displayed as 'Active' tasks (since the system implements preemptive multitasking, the change from ready to running and back is so quick that distinguishing ready and running tasks is pointless because they will all get a slice of the processor within a second). All active tasks can be displayed with the 'A' command.
Terminated tasks are displayed as completed tasks with the reason for termination, EOT for normal 'end of task', and DSed with a reason for a process failure. All processes are assigned a mix number, and operators can use this number to identify a process to control. One such command is the DS command (which stands for either Delete from Schedule, DiScontinue, or Deep Six, after the influence of Navy personnel on early computer projects, depending on who you talk to). Tasks terminated by the operator are listed in the complete entries as O-DS.
Tasks can also terminate due to program faults, marked as F-DS or P-DS, for faults such as buffer overflow, numeric overflow, etc. Completed entries can be listed by the operator with the 'C' command.
Tasks waiting on a resource are listed under the waiting entries and the reason for waiting. All waiting tasks may be listed with the 'W' command. The reason for waiting is also listed and more information about a task may be seen with the 'Y' command. It may be that a task is waiting for operator input, which is sent to a task via the accept 'AX' command (note that operator input is very different from user input, which would be input from a network device with a GUI interface).
Tasks waiting on user input or file reads would not normally be listed as waiting entries for operator attention. Another reason for a task to be waiting is waiting on a file. When a process opens a file, and the file is not present, the task is placed in the waiting entries noting that it is waiting on a certain file. An operator (or the user that owns the process) has the opportunity to either copy the file to the expected place, or to redirect the task to read the file from another place, or the file might even be created by an independent process that hasn't yet completed.
If the resource cannot be provided by the operator, the operator can DS the task as a last resort. This is different to other systems which would automatically terminate a task when a resource such as a file is not available. The MCP provides this level of operator recoverability of tasks. Other systems force programmers to add code to check for the presence of files before accessing them, and thus extra code must be written in every case to provide recoverability, or process synchronization. Such code may be written in an MCP program when it is not desirable to have a task wait, but because of the operator-level recoverability, this is not forced and therefore makes programming much simpler.
MCP thus provides a very fault-tolerant environment, not the crash-and-burn core-dump of other systems.
As with file attributes, tasks have attributes as well, such as the task priority (assigned at compile time, execution time, or can be changed while the task is running), processor time, wait time, status, etc. These task attributes can be accessed programmatically as can file attributes of files.
Software Components and Libraries
MCP libraries provide a way of sharing data and code between processes. The article on the B5000 looks at the way dependent processes could be asynchronously run so that many processes could share common data (with the mechanisms to provide synchronized update). Such a family of related processes had to be written as a single program unit, processing procedures at higher lex levels as the asynchronous processes which could still access global variables and other variables at lower lex levels.
Libraries completely inverted this scenario with the following advantages:
• Libraries and independent processes are written as independent programming units
• Libraries completely controlled access to shared resources (data encapsulation and hiding)
• Libraries and clients could be written in different languages
• Process switching was not required to safely access data
So clean and radical was the library mechanism that much system software underwent major rewrites resulting in a better structured systems and performance boosts.
Libraries were introduced to MCP systems in the early 1980s having been developed by Roy Guck and others at Burroughs. They are very much like C.A.R. Hoare's monitors and provide mutual exclusion and synchronization between client processes, using MCP EVENTs and the Dahm locking technique. The advantage is that all synchronization is provided in the library and client code does not need to worry about this level of programming at all. This results in robust code since clients can't undermine the synchronization code in the library. (Some would call this a 'Trusted Computing Initiative'.)
Libraries are more sophisticated forms of libraries on other systems such as DLLs. MCP libraries can be 'shared by all' or 'private'. The private case is closest to libraries on other systems – for each client a separate copy of the library is invoked and there is no data sharing between processes.
Shared by all is more interesting. When a client starts up, it can run for a while until it requires the services in the library. If the library were already running, the client was checked for a compatible interface (all parameters and return types of imported procedures checked) and the client then linked to the library.
If this was the first invocation of the library the library would run its main program (outer block in an ALGOL program) to initialize its global environment. Once initialization was complete, it would execute a freeze, at which point all exported entry points would be made available to clients. At this point, the libraries stack was said to be frozen since nothing more would be run on this stack until the library became unfrozen, in which case clean-up and termination code would be run. When a client calls a routine in a library, that routine runs on top of the client stack, storing its locals and temporary variables there. This allows many clients to be running the same routine at the same time, being synchronized by the library routine, which accesses the data in the global environment of the library stack.
Freeze could also be in two forms – temporary and permanent. Temporary meant that once the client count dropped to zero, the library would be unfrozen and terminated. Permanent meant that the library remained available for further clients even if the client count dropped to zero – permanent libraries could be unfrozen by an operator.
Libraries could also be accessed 'by title' and 'by function'. In 'by title' the client specified the file name of the library. 'By function' was an indirect method where a client would just specify the function name of the library, for example 'system_support' and the actual location of the library is found in a table which had been previously set up by an operator with 'SL' (system library) commands, for example 'SL system_support = *system/library/support'. MCP's fault tolerant attitude also works here – if a client tries accessing a library that is not present, the client is put in the 'waiting' tasks and the library could be made present, or the request redirected.
Libraries can also be updated on the fly, all that needs to be done is to 'SL' the new version. Running clients will continue to use the old version until they terminate and new clients will be directed to the new version.
The entire database system is also implemented with libraries providing very efficient and tailored access to databases shared between many clients.
Another IPC technique is port files. They are a like Unix pipes, except that they are generalized to be multiway and bidirectional. Since these are an order of magnitude slower than other IPC techniques such as libraries, it is better to use other techniques where the IPC is between different processes on the same machine.
Port files real application, therefore, is for distributed IPC. Port files were introduced with BNA (Burroughs Network Architecture), but with the advent of standard networking technologies such as OSI and TCP/IP, port files can be used with these networks as well.
A server listening for incoming connections declares a port file (a file with the KIND attribute equal to PORT). Each connection that is made from a client creates a subfile with an index, so each port file represents multiple connections to different clients around the network.
A server process receives client requests from anywhere on the network by issuing a read on the port file (subfile = 0 to read from any subfile). It issues a response to the client that issued the request by writing to the particular subfile from which the request was read.
The MCP also provides a sophisticated yet simple operator environment. For large installations, many operators might be required to make physical resources, such as printers (loading paper, toner cartridges, etc) available. Low-end environments for small offices or single user may require an operator-free environment (especially the laptop implementation).
Large systems have dedicated operations terminals called ODTs (Operator Display Terminals), usually kept in a secure environment. For small systems, machines can be controlled from any terminal (provided the terminal and user have sufficient privileges) using the MARC program (Menu Assisted Resource Control). Operator commands can also be used by users familiar with them.
Operator commands are mostly two letters (as with Unix), and some are just one letter. This means that the operator interface must be learned, but it is very efficient for experienced operators who run a large mainframe system from day to day. Commands are case insensitive.
Tasks are entered in the program 'mix' and identified by mix numbers, as are libraries. To execute a program, operators can use the 'EX' or 'RUN' command followed by the file name of the program. ODTs are run typically with ADM (Automatic Display Mode) which is a tailorable display of system status usually set up to display the active, waiting, and completed mix entries, as well as system messages to the operator for notifications or situations requiring operator action.
Complete listing of these displays are given by the 'A' (active), 'W' (waiting), 'C' (completed), and 'MSG' (message commands).
If a task becomes waiting on some operator action, the operator can find out what the task needs by entering its mix number followed by the 'Y' command. (Note the object-oriented style of commands, selecting the object first, followed by the command.) For example, '3456Y'.
An operator can force a task into the waiting entries with the stop command '3456ST' and make it active again with OK: '3456OK'. The OK command can also be used when an operator has made a resource available for a task, although more frequently than not, the MCP will detect that resources have become available, CAUSE the EVENT that processes have been waiting on without further operator intervention.
As well as tasks and processes, operators also have control over files. Files can be listed using the FILE command, copied using COPY, removed using REMOVE, and renamed.
The operating environment of the MCP is powerful, yet simple and usually only requires a fraction of the number of operators of other systems.
An important part of the operations environment is the high-level Work Flow Language
All actions in the system are logged, for example all messages displayed to the operator, and all operator actions. All significant program actions are also logged, for example BOJ for beginning of a WFL job, BOT for beginning of a task within a WFL job, EOT and EOJ for end of tasks and jobs. As well, all file and database open and closes are logged. This used to contribute to an apparent slowness of the MCP operating environment compared to systems like Unix, since everything was logged, but as systems like Unix have become more security conscious, it too keeps many things in the system logs.
The logs can be used for forensics to find out why programs or systems may have failed, or for detecting attempts to compromise system security. Logs are automatically closed after a system-settable period and a new one opened. Opened and closed logs contain a huge amount of information and this can be filtered and analyzed with programs such as LOGANALYZER.
The MCP was the first OS developed exclusively in a high-level language. Over its 45 year history it has had many firsts in a commercial implementation, including virtual memory and a high-level job control language (WFL). It has long had many facilities that are now only appearing in other widespread operating systems, and together with the B5000 hardware architecture, the MCP provides a very secure, high performance, multitasking and transaction processing environment.
"Master Control Program" was also the name of the power hungry computer in the Disney movie Tron (1982) directed by Steven Lisberger, starring Jeff Bridges, David Warner, Bruce Boxleitner, Condy Morgan, and Barnard Hughes.
IMDB listing: