• Nem Talált Eredményt

Definition and Action modules must never get ahead of the Control module. This is because this module, which processes statements

in class (c) above, handles jumps and other transfers of control (amongst other things), and it is clearly essential that no other module should pass such a statement until it has been fully processed by the Control module.

3 ) Any module which encounters an undefined variable when it is attempting to process an otherwise acceptible statement must wait until the variable becomes defined, or until all the other modules have caught up with it. If it is still undefined then the variable must have been used before it was defined in the source part-program, and an error must be recorded.

The first two constraints are invariant, and define the broad basis for synchronisation, while the third is a dynamic factor which essentially requires a module to suspend itself according to the state of other modules of whose existence it is unaware! Furthermore, the modules themselves need not be dirctly aware of the constraints, since all communication with common data and the Executive is handled by the low-level monitor procedures in the modules, which are themselves only accessed via the user- oriented high-level monitor procedures referred to earlier. Nevertheless, the synchronisation of the various modules becomes a remarkably straight­

forward affair because the necessary tools are already part of the system.

The first two rules, above, state that the Input module must never fall behind any other modules, and that the Control module must never fall

88

-behind any of the Definition or Action modules. There is no need for any system of semaphores (or any other synchronising device) to achieve this because the perfect mechanism already exists - namely, the stream of intermediate language commands. All that is necessary is for the Input module to record whenever it writes an I.L. record, and for the other modules to record when they read one, and all the relevant information is available. This is the central principle which governs the Executive module.

We can define four main types of communication between the modules and the Executive, namely those in which a module

a) requires access to the common data base

b) requires access to the intermediate language file c) wishes to send information to the output file(s) d) needs to initiate some specific synchronisation

In the initial implementation the data base is subdivided into two parts - the Name Table, w h i c h contains all the symbols used and their lexical and/or syntactic classes, and the Surface Data Table, which replaces the APT-like Canonical Forms area as the source of data concerning the various geometric surfaces. Other types of data could be added if required, but this class of communication is distinguished by the fact that, as long as the basic synchronisation rules are being obeyed, the order in which the modules happen to be running is of no consequence.

Access to the Intermediate Language file, on the other hand, is the primary synchronisation method. When the Input module writes an I.L.

record it informs the Executive, which updates a table showing the stage (or I.L. record) reached by each module. When a module wishes to read an I.L. record it asks the Executive for the sequence number of the next record. If rules 1 and 2 are satisfied then the module is given the required sequence number and can read this record directly. This technique also deals with jumps or other interruption of the normal sequence, as the appropriate sequence number can be communicated to other modules as and when necessary. If the reading of an I.L. record would infringe the synchronisation rules then the module must be suspended until the situation has cleared. In order to fully synchronise the system, therefore, the Executive module must know about the special position of the Input and

Control modules, and also the number of other modules, so that appropriate tables can be kept. The latter information can be provided at run-time (for example, by a macro which runs the system), while the former is knowledge about the permanent parts of the system; the requirement for freely added or removed modules is not, therefore, infringed.

Access to the output files, in particular the printer, is a further problem since the information to be printed (or otherwise output) will be produced in a random order but must be output in a sequential order related to the original source program. Once again, the knowledge of the stage reached by each module can be used to decide whether such output should be output directly or stored in a buffer for output later in the correct order. Experiments have led to the adoption of a five-line buffer for each module; if a module's buffer is full then it must be suspended until some of the buffer contents have been output.

The final type of communication relates to requests from a module for it to be suspended until one or more other modules catch up with it. This may be due to an undefined variable, as discussed above, or to a jump, or to some exception condition such as the end of the program, or to an error.

All that is required, however, is for the Executive to suspend the module until some condition (normally that the other modules reach the same stage) is satisfied.

The skeleton system developed to verify these principles was written in Algol 68 [van Wijngaarden et al, 1969, 1975] because this is a powerful language providing all the necessary tools for system p r o gramming

[Holdsworth, 1977], and was available on the 1906S [Woodward and Bond, 1974].

The GEORGE 4 Operating System is an extremely powerful system which contains one little known feature which very greatly simplified the writing of the low-level monitor procedures. This is a concept known as a Communication File [ICL, 1975] which provides a means for information transfer between modules and a means for suspension and re-activation of user modules.

90

-A communication file is a standard GEORGE character file which can be open for reading by any number of programs simultaneously and also for appending to (i.e. writing after all existing records) by any number of programs, not necessarily the same ones as are reading the file. However, if a reader attempts to read a record after the last one that has so far been written to the file then that program is suspended by the operating system until either a further record is appended to the file or there are no more programs remaining in the computer which are allowed to write to the file. In the first case the program is re-activated and will continue (by reading the next record); in the second case it will fail.

The low-level synchronisation and message passing is thus dealt with by the operating system, although it would not, of course, be difficult to write a suitable set of communication procedures oneself if they were not already available. The communication file has two further advantages, however.

The first of these is that, when used as described above, the file is preserved and can be listed when the processing is complete. This provides a detailed record of the way in which the various modules proceeded and interacted with each other. In a multiprocessing environment (or a simulation of one) this is a very useful diagnostic tool and was, for example, very valuable in examining the effect of different sizes of output buffers for printed output.

The second useful feature is that a program does not necessarily have to read a record from the file - it may also read it directly from the file buffer before it is written to the file (if it is quick enough). In a great many cases, therefore, a record is transferred from module to Executive, or vice-versa, without first being written to a file and then read from there.

A further feature in a production environment is that of a destructive read. In this mode, the reading of a record by all of those programs which are allowed to read it will cause the record to be deleted. Thus only those records which still have to be read by one or more modules will exist at any time, and at the completion of processing the whole file will have been destroyed. When considered together with the possibility of the

within-memory transfers it can be seen that in many situations the record(s) may never actually get witten to the file.

Essentially, therefore, the GEORGE communication file acts as a message queuing system with the feature that any program which attempts to read beyond the end of the queue is automatically suspended (in an i d l e wait, not a bus y one) until the queue is lengthened. One such queue (SENDER) is used for all messages to the Executive, while a second (RETURNER) is used for all the replies.

The messages in both files follow broadly the same format and consist of two parts. The first part of each m essage (in either direction) consists of an integer couplet in which the first integer defines the module which sent (or is to receive) the message, while the second integer defines the type of message. Let us begin by examining messages to the Executive.

There are five types of message that m a y be sent to the Executive module, as follows:

1) insertion of an item in the Name Table, or adjustment of its