CENTRAL CIRCULATION BOOKSTACKS The person charging this material is re- sponsible for its renewal or its return to the library from which it was borrowed on or before the Lotest Date stamped Li 3 «?< ««? be Char 9 ed a minimum fee of $75.00 for each lost book. !? "*. - * "■ "■ "« ""*rtW«0 o, book. a~ rw , Mns z sz:^ °" and moy -* ,n *— *- TO RENEW CALL TELEPHONE CENTER, 933-8400 JjNimsiT^Q^ IUINOIS LIBHAHV AT U8BANA-CHAMPA.GM IAPR051! When renewing by phone, write new due date below previous due date. L162 UIUCDCS-R-79-960 /'(CJUk. UILU-ENC 79 1705 PATH PASCAL USER MANUAL by Roy Harold Campbell Ira Ben Greenberg Thomas John Miller THE UBRARX OB IHE APR 1 7 1979 March 1979 Digitized by the Internet Archive in 2013 http://archive.org/details/pathpascaluserma960camp UIUCDCS-R-79-960 PATH PASCAL USER MANUAL by Roy Harold Campbell Ira Ben Greenberg Thomas John Miller March 1979 DEPARTMENT OF COMPUTER SCIENCE UNIVERSITY OF ILLINOIS AT URB ANA- CHAMPAIGN URBANA, ILLINOIS 61801 Supported in part by NASA Grant NSG1471 and NSF Grant MCS 77-09128. TABLE OF CONTENTS 1 INTRODUCTION 1 2 DATA ENCAPSULATION 3 2.1 Scope. 5 2.2 Declaration of Objects. 5 2.3 Structured Types Containing Objects. 6 2.4 Pointers to Objects. 7 2.5 Path Declaration Part. 7 2.6 Type Definition Part. 8 2.7 Variable Declaration Part. 8 2.8 Operation Declaration Part. 9 2.9 Initialization Part. 10 2.10 Operation Invocation. 11 2.11 Restrictions. 12 3 OPEN PATH EXPRESSIONS 13 3.1 Syntax of Open Paths. 13 3.2 Semantics of Open Paths. 14 3.2.1 Grouping Precedence 14 3.2.2 Simplified Discussion of Features 14 3-2.3 Full Discussion of Features 16 3.3 Examples of Open Paths. 20 4 PROCESSES 23 4. 1 Process Syntax. 23 4.2 Creating a Process. 24 4.3 Process Storage Considerations. 25 4.4 Process Lifetimes. 25 4.5 Parameter Restriction. 26 4.6 Priorities. 27 4.7 Delaying Processes. 28 4.8 Interrupt Processes. 28 5 SUMMARY 31 6 REFERENCES 32 APPENDICES A PATH PASCAL SYNTAX B MESSAGES C OPEN PATH ALGORITHMS D PROGRAMMING EXAMPLES E EXTENDED P-CODE F A SUMMARY OF PASCAL P4 Page 1 1 INTRODUCTION. Experimental Path Pascal is designed to investigate the benefits and problems that arise when path expressions are combined with a language to pro- vide a system programming tool. Instead of altering the Pascal language exten- sively, a minimal number of features was added such that Pascal programs still compile and execute. The language can be used as an instructional tool or for the construction of example system programs. This manual describes the Path Pascal features and the implementation on the Cyber and PDP11. Path expressions were introduced as a technique for specifying process synchronization by [Campbell and Habermann, 74] , and further discussed by [Habermann, 75], [Lauer and Campbell, 75], [Flon and Habermann, 76], [Andler, 79] and [Campbell, 77]. Variations of the path expression idea have been pro- posed by [ONERA CERT, 77] and notations that are similar to paths that model system behavior have been developed independently by [Shaw, 77] and [Riddle, 76]. A specification language has also been designed [Lauer and Shields, 78] based upon the use of a path expression notation. Path Pascal is based on the P4 subset of Pascal [Ammann, et al, 76] (see Appendix F for a summary of the P4 subset). The Path Pascal compiler is written in Pascal P4 and will accept any Pascal P4 program that does not use Path Pascal reserved words as identifiers. The modifications to Pascal involved the addition of an encapsulation mechanism (see chapter 3), Open Path expressions [Campbell, 77] (see chapter 4), and processes (see chapter 5). Open Paths are integrated with the encapsulation mechanism to enforce a strict discipline upon the programmer describing shared data objects. All access to encapsulated data is performed by operations synchronized by Open Page 2 Paths. A process invoking such an operation may only execute the operation if permitted to by the Open Path expression associated with the shared data object. The following sections describe Path Pascal in more detail. Motiva- tions for the design of Path Pascal are discussed further in [Miller, 78]. A description of Pascal can be found in the Pascal Report [Jensen and Wirth, 75]. The additional Path Pascal syntax is listed in Appendix A. Appendix B contains the Path Pascal compiler error messages, and the Path Pascal P code interpreter control options, constants, and error messages. Appendix C describes the semantics of Open Path expressions in terms of P and V opera- tions. Appendix D contains several sample programs. Appendix E describes the changes that have been made to the intermediate code (P-Code) for the addi- tional Path Pascal constructs. Page 3 2 DATA ENCAPSULATION . Path Pascal Includes an encapsulation mechanism called an object. Objects allow useful user-defined data structues to be programmed but are not intended as a general solution to abstract data types. They permit synchroni- zation to be associated with shared data and are implemented as an extension of the Pascal structured type facility. An object provides controlled access to a data structure and consists of a declaration of the data structure together with a set of operations which access the values of that structure. Path Pascal allows algorithms to be expressed in the form of routines (procedures, functions, and processes). Operations are constructed from routines (Thus, operations may be defined in terms of calls upon additional routines). Objects and their operations iso- late the internal data representation of values of the object from the rest of a program. This isolation is enforced by restricting manipulations of the data structure of an object to the textual unit comprising the object. Opera- tions are specified by prefixing the declaration of a routine with the reserved word 'ENTRY'. Since Path Pascal permits concurrent asynchronous processes, several processes can try to access an object at the same time. It is necessary therefore to synchronize and coordinate the execution of these operations. This synchronization is specified for each object by an Open Path Expression. BNF for an object is shown below: ::= OBJECT END; Page 4 :: = An example of an object is: CONST nbuf ■ 5; OBJECT PATH nbuf: (1: (fill); 1: (empty) ) END; TYPE buffsize ■ L.nbuf; inbuff » ARRAY [buffsize] OF CHAR; VAR buf: inbuff; nextspot: ring; ENTRY PROCEDURE fill(inchar: CHAR); BEGIN inbuff [nextspot. inpointer] := inchar END; ENTRY FUNCTION empty: CHAR; BEGIN empty := inbuff [nextspot. outpointer] END; END; The example object implements a five character ring-buffer using an array of characters 'inbuf and a pointer scheme whose algorithm and values are determined by the operations 'inpointer' and 'outpointer' on the variable 'nextspot' of type 'ring' (an object declared in an enclosing scope). The example object has an internal data representation constructed from 'inbuf and 'nextspot' and the values of the object are changed by executions of the operations 'fill' and 'empty'. A path expression synchronizes executions of the operations so that the object may be shared between two communicating processes. Page 5 2. 1 Scope . An object defines a block, possibly containing local constants, types, variables, routines, and the object's operations. The scope of all the local identifiers except the names of the operations obeys the standard rules of Pascal. The operation's identifiers are exported to the scope of the block, in which the object is declared and may be invoked within that scope. Thus, the data structures within the object may only be manipulated externally by the execution of an operation. In the buffer example above, neither 'nextspot' nor 'inbuff are defined external to the block of the object. 2.2 Declaration of Objects . Like other Pascal structured types, objects can be defined and named in a type declaration, or can appear directly in a variable declaration. An examples of a type declaration is TYPE ring = OBJECT PATh inpointer , outpointer END; VAR inp, outp: buff size; ENTRY FUNCTION inpointer: buff size; BEGIN inp := inp MOD nbuf + 1; inpointer := inp END; ENTRY FUNCTION outpointer: buffsize; BEGIN outp := outp MOD nbuf + 1; outpointer := outp END; INIT; BEGIN inp := 0; outp := END; END; and an example of a variable declaration is Page 6 VAR id: OBJECT PATH 1: (get) END; VAR count: integer; ENTRY FUNCTION get: integer; BEGIN count :- count + 1; get :■ count END; INIT; BEGIN count :- END; END; Declaring an object in a type declaration allows its associated name to be used to declare variables of that type. An example of this is VAR pointers: ring; Each variable that is declared as an object creates an instance of that object which possesses its own independent 1) block of storage, 2) copy of the object's operations, and 3) synchronization information to control the order in which its copy of the operations are executed. These three items are described, respectively, in an object's 1) object variable declaration part, 2) operation part, and 3) path declaration part. Thus, successive executions of the operation 'get' on the variable 'id' above will return the integer values 1, 2, 3, and so on. 2 . 3 Structured T ypes Containing Objects . Structured types containing objects may be declared and objects may be nested within each other. Recursive object definitions cause a compile time error. Two examples of structured types containing objects are TYPE rec: RECORD fl: ring; f2: OBJECT ... END; f3: integer END; and Page 7 VAR a: array [1 .. 20] of ring; r: rec; 2.4 Pointers to Objects . Pointers to objects or records containing objects may be declared. Examples of such pointer declarations are VAR ptrring: ** ring; ptrrec: " rec; Dynamic variables may be created from type declarations of objects or records containing objects by executing the standard procedure NEW with the appropri- ate pointer argument. Examples of the creation of dynamic variables are NEW (ptrring); NEW (ptrrec); 2.5 Path Declaration Part . The path declaration part consists of a single Open Path expression which serves two purposes. It specifies the synchronization constraints on the object's operations. These constraints must be met before access to the object's data structure is allowed. The path also declares the operation iden- tifiers which are known outside the scope of the object. The compiler checks each path to ensure that each operation id appears exactly once. A path declaration part (shown below in BNF) can be either empty or may contain an open path: ::= | Page 8 Examples of paths are: PATH nbuf: ( l:(£ill); 1: (empty) ) END; PATH inpointer, outpointer END; Open Path expressions are detailed in chapter 4. 2.6 Type Definition Part . Any type definitions may be declared in the type definition part including new object type definitions. It is therefore possible to nest objects in Path Pascal. Type definitions may use simpler type definitions declared global to the object. 2 . 7 Variable Declaration Part . The object variable declaration part declares the local data structure of the object. This local data structure can contain objects and may use type definitions declared global to the object. ::= VAR {; } ; An example of an object variable declaration part is; VAR buf: inbuff; nextspot: ring; This example is taken from an earlier example. Page 9 2.8 Operation Declaration Part . The operation declaration part specifies the routines and operations that can be performed on the local data structure of the object. Operations may be invoked outside of the object but other routines are strictly local and can only be invoked by operations or the initialization part. Operations are distinguished from routines by prefixing them with the reserved word 'ENTRY'. Each operation identifier must appear in the object's path expression in order to be synchronized and exported. ::= { ) ::= | ::= | | : : = ENTRY An example of operation is: ENTRY FUNCTION outpointer: buffsize; BEGIN outp := outp MOD nbuf + 1; outpointer := outp END; (*outpointer*) Operations and routines within an object can invoke other operations and routines declared within the object as long as these invoked operations and routines are declared first or declared to be forward. Synchronization is applied as usual for an invoked operation. An operation can be invoked from within its object as if it were a Page 10 routine. This differs from the notation used when it is invoked from outside its object, as is illustrated in the following example: 1 PROGRAM test ( ... ); 2 VAR ob: OBJECT 3 PATH a, b END; 4 VAR . . . 5 ENTRY PROCEDURE a; 6 BEGIN ... END; 7 ENTRY PROCEDURE b; 8 BEGIN ... a; ... END; 9 PROCEDURE c; 10 BEGIN ... b; ... END; 11 END (* ob *); 12 BEGIN ... ob.a; ... END. The references in lines 8 and 10 only specify the entry operation name, while the reference in line 12 must use the dot notation. Procedures and functions defined within an object may be recursive. However, recursive entry procedures or entry functions may result in deadlock. Processes are described in detail in chapter 5. 2.9 Initialization Part . The Initialization part is an optional block that is used to initial- ize an object's local data structure and create any local processes. The block is Invoked whenever a new instance of that object is declared or dynami- cally created. Labels, constants, types, variables, and routines can be declared within the initialization block. Any identifiers available inside the object are automatically inherited and can be freely accessed or invoked. Operations of the object may be invoked as routines. Page 11 INIT; Examples of initializations are: INIT; BEGIN inp := 0; outp := END; INIT; VAR i: INTEGER; PROCEDURE q ( j: INTEGER ); BEGIN ... END; BEGIN FOR i := 1 TO 10 DO q; END; For object variables that contain further objects in their local data struc- ture, the init blocks of the objects in the data structure are executed first. The use within an init block of variables and routines global to the object is discouraged. Hence, the order in which the local objects' init blocks are executed is left undefined. 2.10 Operation Invocation . Operations may be performed on variables declared as objects. An operation is executed by specifying the variable, a dot, the entry operation and any parameters. This notation is inspired by the Simula 67 dot notation [Dahl et al, 68]. For example, operations can be invoked on variables declared in examples above by nextspot. inpointer a [5] .inpointer r.f 1. inpointer Operations on dynamic variables are invoked by dereferencing the pointer as in the examples Page 12 ptrring~.inpointer ptrrec~.f l.inpointer 2.11 Restrictions . Assignments between variables with the same object type or variables with the same structured type where that structured type contains objects are not permitted because of side-effects caused by the object variables' syn- chronization states. Object variables or structured variables that contain objects are passed as reference parameters to operations. Page 13 3 OPEN PATH EXPRESSIONS . Using processes, it is possible to write programs in Path Pascal which have several independent execution paths. It is generally impossible to know the order in which processes will execute, or the speed with which they will execute. In fact, in systems with multiple processors, it is possible for two processes to physically execute in parallel. Because of this uncertainty, it is important to have a synchronization mechanism which can be used to ensure the integrity of shared data. The Open Path expressions notation for writing synchronization specif- ications is used in conjunction with objects to synchronize process execu- tions. Shared data is represented by an instance of an object. Each object contains exactly one path expression which specifies the legal orders in which the object's operations can be executed, and the ways in which these opera- tions can execute in parallel. Since only these operations are used to access the data, processes trying to manipulate the data are forced to do so in safe sequences. 3. 1 Syntax of Open Paths . ::= PATH END; ::= , ::= ; ::= : () | [] | () | ::= positive constant> An Open Path expression is a list of sequences separated by commas, Page 14 enclosed by the reserved words 'PATH' and 'END'. A sequence is a list of items separated by semi-colons. An item can be an operation name, or a comma separated list of sequences enclosed by parentheses, parentheses with an asso- ciated integer bound, or brackets. Each operation name must appear exactly once in an Open Path. 3.2 Semantics of Open Paths . Intuitively, an Open Path works in the following manner. A process tries to execute an operation. The path's specification dictates whether or not that operation can proceed. If it can, then it does so and the path is advanced to its next state. Otherwise, the process must wait until the path enters a state where the operation that was requested can be executed. Waiting processes are later selected for execution in first-in first-out order. 3.2.1 Grouping Precedence . Semi-colons have a higher precedence than commas. This precedence can be over-ridden by the three grouping notations: parentheses, parentheses with an integer bound, and brackets. 3.2.2 Simplified Discussion of Features . This section introduces the components of an Open Path. The discus- sion is simplified by restricting operands and lists to single operation names. The next subsection generalizes these features and introduces some additional details. Page 15 3.2.2.1 Semi - colon . A semi-colon is used to specify sequentially . The notation X;Y requires an execution of operation X to precede an execution of operation Y, and an execution of Y may only follow an execution of X. 3.2.2.2 Comma . Commas specify a set of alternatives, any one of which can execute next. The path X,Y,Z allows either operation X or operation Y or operation Z to execute next. 3.2.2.3 Parentheses with Bound . This construct is used to limit concurrent execution. The integer bound specifies the maximum number of processes that can be concurrently exe- cuting the operation inside the parentheses. A process may immediately start executing the enclosed operation if fewer processes than the specified integer are concurrently executing the operation. Specifying 1: (X) allows only one process at a time to execute X, i. e. executions of X must be mutually exclusive. The path 3: (X) means that at most three processes can be executing X concurrently. The bound may be used to share a limited number of resources between several processes. 3.2.2.4 Parentheses . Parentheses without an associated integer are equivalent to parentheses with an associated integer of infinity. They are only used for grouping and do not limit concurrent execution. The expression (X) is Page 16 equivalent to 'infinity: (X)' and allows up to an unlimited number of con- current executions of X. 3.2.2.5 PATH and END. The keywords 'PATH' and 'END' delimit the entire path expression and are equivalent to a pair of parentheses. The path PATH X END would allow an unlimited number of concurrent executions of X. 3.2.2.6 Brackets . Brackets permit a burst of execution. The burst begins when some pro- cess starts to execute the operation enclosed by the bracket. The burst is continued as long as some process is still executing the operation. While the burst is active, an unlimited number of processes can immediately begin the operation. The burst ends when the last process which is executing the opera- tion completes. In the path [X] a process can immediately start executing X if 1) at least one process is currently executing X, or 2) the path is in a state where [X] can start executing. Otherwise, that process must wait until the path enters a state where [X] can be started again. 3.2.3 Full Discussion of Features . 3.2.3.1 Definitions . A list of comma separated sequences is referred to as an Open Path list. Thus an Open Path expression is an Open Path list enclosed by 'PATH' and 'END'. Examples of Open Path lists are X,Y,Z and V, (W;X;Y) ,2: (Z) and the sim- ple list X- Page 17 Operation names in an Open Path list are called initial, intermediate, or final operations. Initial operations are those operations in an Open Path list which can be executed when the path is in a state where the Open Path list can be started. Final operations are those operations in an Open Path list whose execution puts the path in a state where the parts of the Open Path expression that follow the Open Path list can start to execute. Intermediate operations are those operations in an Open Path list which can be executed between the Open Path list's initial and final operations. In 'X,Y,Z', X, Y, and Z are both initial and final operations, and there are no intermediate operations. In 'V, (W;X;Y) , 2: (Z ) ' , V, W, and Z are initial operations, X is an intermediate operation, and V, Y, and Z are final operations. A sequence of operation executions that starts with one of an Open Path list's initial operations and ends with one of its final operations is called an execution sequence. In 'V, (W;X;Y)' , V is an execution sequence and so is W, X, and Y. A sequence of operation names can be used in more than one execution sequence. For example, two processes can be concurrently executing V according to the above Open Path list yielding two similar execution sequences, V and V. The grouping notations inherit the characteristics of the Open Path list which they enclose. Thus brackets in [V,(W;X;Y)] have initial operations of V and W, and an execution sequence of W, X, and Y. 3.2.3.2 Brackets . Brackets are used for grouping and to provide a special burst mode of execution. A burst of execution is started when one of the bracket's initial operations is executed and continues as long as any of the bracket's execution Page 18 sequences is unfinished. One of the bracket's initial operations can be exe- cuted immediately if one of the bracket's execution sequences is unfinished. There are two special rules for brackets. First, while a bracket's operations must wait to start until some execution sequence progresses to the point where the bracket is reached, once the bracket has been started (entered burst mode) an unlimited number of the bracket's operations can start immedi- ately as long as one of the bracket's execution sequences is still unfinished. Second, only one execution sequence can contain the bracket in burst mode; i. e. a bracket must be executed in mutual exclusion. This rule is a result of the decision to continue an old burst instead of start a new one when the bracket is in burst mode. 3.2.3.3 Parentheses with Bound . This construct is used for grouping and to limit concurrent execution. It states that at most n execution sequences can proceed concurrently (n is the associated integer). If there are fewer than n concurrent execution sequences, one of the parentheses' initial operations can be executed immedi- ately. There is a special rule when this construct is nested. If an attempt is made to execute an operation which is nested within several pairs of parentheses and which could execute if not limited by one of these constructs, the execution restrictions associated with the parentheses are examined from the innermost level. If execution is restricted then the process that was try- ing to execute the operation waits at the level where it was stopped. When the restriction is removed, checking continues from that point. In the path i: (Y,2: (Z)), assuming that the execution sequences Z and Z are unfinished (i. Page 19 e. two processes are executing Z), a process now attempting to execute Z will be stopped by 2:(Z). If another process then attempts to execute Y it wili be permitted to continue. The third attempt to execute Z would not have 'used up' one of the outer parentheses' execution sequences. This rule helps prevent poor system performance. 3.2.3.4 Parentheses . Parentheses are used for grouping and are equivalent to parentheses with an associated integer of infinity. 3.2.3.5 PATH and END . 'PATH' and 'END' are equivalent to a pair of parentheses end enclose the Open Path expression. 3.2.3.6 Semi-colon . The path LI; L2 (where LI and L2 are open path lists) allows L2 to being only after some LI is completed. 3.2.3.7 Comma - Any of the operands in a comma separated list can be group enclosed Open Path lists. The path LI, L2, ..., Ln, allows any one initial operation of any of the operands to be executed. Thus any one execution sequence from the operands can be executed. Page 20 3.3 Examples of Open Paths . 1. PATH A END; A can execute at any time, and any number of A's can execute concurrently. The synchronization that is specified is trivial. 2. PATH A,B,C END; A or B or C can execute at any time. Any number of A's, B's, and C's can execute concurrently. The synchronization that is specified is trivial. 3. PATH A;B END; A's can be executed at any time. A B can only be executed if the number of B's that completed or are currently executing is less than the number of A's that are completed. Any process that is given permission to execute can execute concurrently with any other process. 4. PATH 1: (A) END; A's must be executed sequentially. 5. PATH 2: (A) END; At most two A's can execute concurrently. 6. PATH 1: (A),B END; A's must execute sequentially. B's can execute at any time. Any processes that are given permission to execute can execute concurrently. 7. PATH 1: (A),l: (B) END; A's must execute sequentially, and B's must execute sequentially. One A and one B can execute concurrently, however. 8. PATH 1: (1: (A),l: (B)) END; Processes A and B execute in mutual exclusion. The expression PATH 1: (A, B) END would be better. Page 21 9. PATH 5: (A;B) END; At most five execution sequences can be executing concurrently. Thus at most 5 A's and B's can be executing concurrently, or 4 A's and 1 B, etc. In addition, the number of B's tht are executing or completed must be less than the number of A's that are completed. 10. PATH 1: (1: (A),B) END; The outer parentheses specifies that only one A or one B can execute at a time, and that they cannot execute concurrently. The inner parentheses allow B's to be given priority over A's. This occurs because processes trying to execute A's must first get past the restriction of the inner parentheses, while processes trying to execute B's can go directly to the outer parentheses. 11. PATH 1: ( [A] ,B) END; Either a burst of A's or a B can execute, but not concurrently. The A's in the burst of A's must execute concurrently. When the burst ends, a B will start if a process is waiting to execute a B. Otherwise, either a burst of A's or a B will be executed depending upon whether an A or a B is requested first. 12. PATH 3: ([A]) END; This path is equivalent to PATH 1:([A]) END;, PATH [A] END;, and PATH A END; because bursts must execute sequentially and there is no difference between sequential bursts of A's and the unrestricted execution of A's. 13. PATH 5: (3: (A), 4: (B)) END; At most 3 A's can execute sequentially, and at most 4 B's can execute sequentially. The outer parentheses allow at most 5 concurrent execution sequences, so at most 3 A's and 2 B's, or 2 A's and 3 B's, etc. can exe- cute concurrently. The bounded parentheses can be used to allocate resources. The above expression could be used to allocate five resources to two sets of processes invoking A and B so that there is always one resource available for the set requesting A and two resources available for the set requesting B. 14. PATH 8: (3: (A), 3: (B)) END; This path is equivalent to PATH 6: (3: (A) , 3: (B ) ) END. Setting the outer integer to 8 is superfluous. At most 3 A's can execute concurrently, and at most 3 B's can execute concurrently. Also, all 3 A's and all 3 B's can execute concurrently. Page 22 15. PATH TOTAL:(AMAX:(A),BMAX:(B)) END; If TOTAL, AMAX, BMAX, are integer constants 5, 3, and 4, then this path is identical to the path in 13. Page 23 A PROCESSES . A process is a program structuring unit which has an independent execution path associated with it. Processes can interact and are co- ordinated by performing operations on shared variables. The declaration of a process is, in Path Pascal, distinguished from the activation of a process. A process may be declared in any block and activations of the process may be created in any body of code with scope that includes the declaration. 4.1 Process Syntax . ::= :: = PROCESS ; | PROCESS ( {;}); : : = [] Processes are declared like standard Pascal procedures. They may possess parameters, but may also have a size attribute. The parameters can be passed by value or by reference. The size attribute is used to estimate the process's storage requirements. If it is omitted a default value is used. An example of a process declaration is: Page 24 1 PROCESS printer [200] ( VAR inbuff : buffer); 2 VAR outbuff : buffer; ch : CHAR; 3 4 PROCEDURE asciitoebcdic ( ch : CHAR); 5 BEGIN 6 outbuff. fill(ch) 7 END; 8 9 PROCESS reader; 10 VAR ch : CHAR; 11 BEGIN 12 REPEAT 13 ch := inbuff .empty; 14 asciitoebcdic(ch) 15 UNTIL false 16 END; 17 18 BEGIN 19 reader; (* instantiate a reader process *) 20 REPEAT (* simulate a writer *) 21 ch := outbuff .empty; 22 write(ch) 23 UNTIL false 24 END; (* printer *) This example contains a printer which manipulates and then prints sequences of characters. The printer has one parameter, 'inbuff a variable of type 'buffer' , and a size attribute of 200. The size attribute indicates that 200 words will be required at run-time to contain the stack and heap for the pro- cess printer. The 200 words are required for the local variables and for invocations of routines. 'Reader' transforms ascii characters in 'inbuff to ebcdic characters using 'asciitoebcdic'. The ebcdic characters are placed in 'outbuff and then printed using the write loop. 4 . 2 Creating a_ Process . An instance of a process is dynamically created by invoking the pro- cess name , Just as in a procedure invocation. This can be seen in line 19 in the above example where the reader process is created. The creating process Page 25 does not have to wait for the created process to terminate before continuing its own execution. Each process created is allocated a run-time heap and stack from the heap of the process which is performing the creation. The number of words allocated is specified by the size attribute, but if this attribute is omitted a system default of 100 words is used. No mechanism is provided to abnormally terminate a process. A process terminates only when it reaches the end of its code body. 4 . 3 Process Storage Considerations . A process's storage may be explicitly released and reused with the procedures MARK and RELEASE just like dynamic variable storage. It is not automatically released when a process terminates. Note, however, that it is an error to release this storage before a process completes just as it is incorrect to release a dynamic variable's storage before reaccessing that variable. Also, notice that MARK will only refer to the active process's local heap . 4.4 Process Lifetimes . The lifetime of a block which contains a process declaration is at least as long as the lifetime of any activation of that process. Intervening blocks between the block that contains the process declaration and the pro- cess creation, can complete before the process completes. Thus a block B (which does not contain the process declaration) can create a process, con- tinue executing, and then return control to its calling block. Later control can reenter block B and another creation of the process can be made, even if the first process is still executing. If an attempt is made to exit a block Page 26 which contains a process declaration for which there is an existing activa- tion, the exit will be delayed until that process completes. The following example illustrates these points. PROGRAM example( input, output); VAR w : INTEGER; PROCESS a; BEGIN ... END (*a*); PROCEDURE b(VAR x : INTEGER); VAR y : CHAR; PROCEDURE c(VAR z : CHAR); BEGIN a END (*c*); BEGIN c(y) END (*b*); BEGIN b(w) END (*example*). The program block calls 'b' which calls 'c' which creates process 'a'. *c* can then continue executing and complete, returning control to 'b'. The process 'b' can now continue executing in parallel with the activation of 'a' and can complete, returning control to the program block. The program block can continue executing, but it cannot complete until process 'a' has ter- minated. 4 . 5 Parameter Restriction . The scope of an actual parameter which is passed by reference to a process must contain scope of the process's declaration. Consider the following exam- ple where this rule is violated: Page 27 PROCESS a (VAR x : INTEGER); BEGIN ... END; PROCEDURE b; VAR y : INTEGER; BEGIN a(y) END; PROCEDURE c; BEGIN ...END; Calling 'b' creates 'a' and passes 'y* by reference, completes, and returns its activation record to the run-time stack. The routine which called 'b' might now call 'c' whose activation record will overlay some or all of the space where 'b's old activation record was stored. If 'a' is still executing and it writes into 'y', it will erroneously write into 'c's activation record. 4.6 Priorities . One of two static priority schemes can be associated with processes in order to provide rudimentary control over process scheduling. In the first scheme, all processes have the same priority. In the other, priority is deter- mined by the static nesting level of a process's declaration, with processes declared at the outermost levels having the highest priority. Within a given priority level, a process is selected for execution by a first-in first-out scheduler. If the level oriented scheme is used in the above example, then the writer has higher priority than the reader and the device driven by 'write' (line 22) is kept as busy as possible. The second priority scheme is selected by default, but equal priorities can be chosen by specifying the NP option on the interpreter command card. Page 28 4.7 Delaying Processes . A process can be delayed for a fixed time interval by calling the pro- cedure DELAY. An integer argument specifies how long the process is to be delayed. The number of simulated time units which have elapsed since execu- tion began can be obtained from the parameterless function TIME which returns an integer value. 4.8 Interrupt Processes . Interrupt processes are used in Path Pascal to program input and out- put devices of the computer. The DOIO statement is used within the interrupt process to suspend it while input or output is being performed. Only one DOIO statement is allowed within the process block. The DOIO statement may not be used in regular processes. The interrupt process mechanism is based on Modula [Wirth,77] and its syntax is show below in BNF: ::«= PROCESS interrupt params>; | PROCESS ( { ; } ); ::^ [ PRIORITY - ; VECTOR -
]
::- // mp le:- Page 29 INTERRUPT PROCESS print [PRIORITY - 4 ; VECTOR = #64] (buf : linebuffer); VAR 1: INTEGER; pts [#177564] :bits; (*printer status word*) ptb [#177566] :char; (*printer buffer word*) BEGIN i :« 0; REPEAT i := 1+1; pts := [6]; (*enable printer interrupt*) ptb := buf [i]; (*print a character*) DOIO; (*wait for the interrupt to occur*) pts := pts-[6]; (*disable printer interrupt*) UNTIL (( i >= linesize ) OR (buf[i] = cr)); END; (*end of process print*) The interrupt parameter is used to store the interrupt vector of the process at the correct place in memory and set the priority of the process. In the example, the vector will be stored at octal location 64 and the priority of the process will be 4. (On the PDP11, the priority of the processor is set to the priority of the process it is running. Interrupts from devices can only affect the process when the process priority is less than the priority of the interrupting device. Other processes run with a processor priority of 0. ) Interrupt processes are created in exactly the same manner as other processes. Running duplicate interrupt processes or terminating an interrupt process while an interrupt is pending is discouraged. The device registers of the printer are, in this example, at location #177564 and #177566. To allow programs to access device registers, variables can be associated with the absolute device addresses. ::= {, > : Page 30 ::■ [
] Thus, "pts" and 'ptb" are declared to be the status and data registers of the printer. The variable "pts" is declared to be of type "bits", a set of numbers from 1 to 16. The interrupt for the printer is enabled by writing a bit into the status register. This is performed above using one of the operations on sets. The DOIO statement, when executed, suspends the process until the inter- rupt is received. Another process is removed from the ready queue and run. Machine dependent features such as device addresses and the DOIO statement are restricted in their use to the block of an interrupt process. Page 31 5 SUMMARY . The Path Pascal programming language is an extension of Pascal P4 which includes concurrent processes, processes for controlling I/O devices, path expressions, and objects. The Path Pascal compiler is written in Pascal P4 and is self -compiling. An intermediate code (an extended P-Code) is produced by the Path Pascal compiler and can either be executed interpretively or assembled into machine instructions. The language can be used to simulate sys- tens, as an educational tool, or to construct system and real-time programs. Page 32 REFERENCES. [Andler,1979] Andler, Sten, "Predicate Path Expressions", 6th Annual ACM Symposium on Principles of Programming Languages, San Antonio, Tex., 1979, pp. 226-236. [Ammann, Nori, and Jacobi,76] Ammann, U. , Nori, K. , and Jacobi, C, "The Portable Pascal Compiler", Institut Fuer Informatik, Eidg. Technische Hochschule CH-8096 Zeurich, 1976. [Campbell and Habermann, 74] Campbell, R. H. and Habermann, A. N. , "The Specification of Process Syn- chronization by Path Expressions," Lecture Notes in Computer Science, Springer Verlag, Volume 16, 1974, pp. 89-102. [Campbell, 77] Campbell, R. H. , "Path Expressions: A technique for specifying process synchronization," Ph.D. Thesis, The University of Newcastle Upon Tyne, August, 1976. [Dahl et al,68] Dahl, 0. J., Myhrhaug, B., and Nygaard, K. , "The Simula 67 Common Base Language," Norwegian Computer Center, Oslo, 1968. [Flon and Habermann, 76] Flon, L. and Habermann, A. N. , '^Towards the Construction of Verifiable Software Systems," SIGPLAN Notices, Volume 8, Number 2, March, 1976. [Habermann, 75] Habermann, A. N. , "Path Expressions," Technical Report, Carnegie-Mellon University, 1975. [Habermann, 76] Habermann, A. N. , "Introduction to Operating System Design", Science Research Associates, 1976, p. 89. [Jensen and Wirth,75] Jensen, K. and Wirth, N. , Pascal User Manual and Report , Springer-Verlag, 1972. [Lauer and Campbell, 75] Lauer, P. E. and Campbell, R. H. , "Formal Semantics of a Class of High Level Primitives for Co-ordinating Concurrent Processes," Acta Informa- tica, Volume 5, 1975, pp. 297-332. [Lauer and Shields , 1978] Lauer, P. E. and Shields, M. W. , "Abstract Specification of Resource Accessing Disciplines: Adequacy, Starvation, Priority and Interrupts," Slgplan Notices, Volume 13, Number 12, 1978, pp. 41-59. Page 33 [Miller, 78] Miller, T. J., "An implementation of Path Expressions in Pascal," M.S. Thesis. University of Illinois, Urbana, May, 1978. [ONERA CERT, 78] "Parallelism, Control and Synchronization Expressions in a Single Assign- ment Language," SIGPLAN Notices, Volume 13, Number 1, January, 1978, pp. 25-33. [Riddle, 76] Riddle, W. E., "Software System Modelling and Analysis," RSSM/25, Tech. Report, Department of Computer and Communicatin Sciences, University of Michigan, July, 1976. [Shaw, 77] Shaw, A. C, "Software Descriptions with Flow Expressions," Department of Computer Science, University of Washington, October, 1977. [Wirth,77] Wirth, N., "Modular a Language for Modular Multiprogramming," Software- Practice and Experience, Volume 7, 1977, pp. 3-84. Page A-l APPENDIX A PATH PASCAL SYNTAX The following Backus-Naur form (BNF) grammar summarizes the syntax of Path Pascal. This list of rules only contains the additions to standard Pas- cal. The following symbols are meta-symbols belonging to the BNF formalism and are not symbols of the language Path Pascal. I ::« { > The curly braces denote the possible repetition of the enclosed symbols zero or more times. ::=