Concurrent Pascal: Difference between revisions

From HandWiki
imported>SpringEdit
add
 
JTerm (talk | contribs)
update
 
Line 35: Line 35:
*[[Data structure alignment|Packed array]]s
*[[Data structure alignment|Packed array]]s
*[[Pointer (computer programming)|Pointer types]]
*[[Pointer (computer programming)|Pointer types]]
*File types, and associated standard [[Input output|input/output]] procedures
*File types, and associated standard input/output procedures


These omissions make it possible to guarantee, by a combination of compile-time checks and minimal run-time checking in the threaded-code interpreter, that a program can not damage itself or another program by addressing outside its allotted space.
These omissions make it possible to guarantee, by a combination of compile-time checks and minimal run-time checking in the threaded-code interpreter, that a program can not damage itself or another program by addressing outside its allotted space.
Line 51: Line 51:
==Example==
==Example==
The following example shows the declaration of a simple monitor, and its use by two communicating processes.
The following example shows the declaration of a simple monitor, and its use by two communicating processes.
<source lang="componentpascal">
{{pre|1=
type
type
     "Bounded buffer monitor"
     <u>''"Bounded buffer monitor"''</u>
     buffer = Monitor
     buffer = Monitor
         var
         var
             saved        : Integer;  "saved item is an integer"
             saved        : Integer;  <u>''"saved item is an integer"''</u>
             fullq, emptyq : Queue;    "used by only two processes"
             fullq, emptyq : Queue;    <u>''"used by only two processes"''</u>
             full          : Boolean;  "true if an item is saved:"
             full          : Boolean;  <u>''"true if an item is saved:"''</u>


         "Puts item in buffer"
         <u>''"Puts item in buffer"''</u>
         procedure entry put(item : Integer);
         {{codett|2=pascal|procedure entry put(item : Integer);}}
             begin
             begin
               if full then
               {{codett|2=pascal|if full then}}
                   delay(fullq);      "block if full"
                   delay(fullq);      <u>''"block if full"''</u>
               saved := item;        "save the item"
               saved := item;        <u>''"save the item"''</u>
               full := true;          "mark as full"
               full := true;          <u>''"mark as full"''</u>
               continue(emptyq)      "unblock consumer"
               continue(emptyq)      <u>''"unblock consumer"''</u>
             end;
             end;


         "Gets item from the buffer"
         <u>''"Gets item from the buffer"''</u>
         procedure entry get(var item : Integer);
         {{codett|2=pascal|procedure entry get(var item : Integer);}}
             begin
             begin
               if not full then
               {{codett|2=pascal|if not full then}}
                   delay(emptyq);    "block if empty"
                   delay(emptyq);    <u>''"block if empty"''</u>
               item := saved;        "get the item"
               item := saved;        <u>''"get the item"''</u>
               full := false;        "mark as not full"
               full := false;        <u>''"mark as not full"''</u>
               continue(fullq)        "unblock producer"
               continue(fullq)        <u>''"unblock producer"''</u>
             end;
             end;


         "Initialize the monitor"
         <u>''"Initialize the monitor"''</u>
         begin
         begin
             full := false
             full := false
         end;
         end;


     "Producer uses a buffer"
     <u>''"Producer uses a buffer"''</u>
     producer = process(pass : Buffer);
     producer = process(pass : Buffer);
         var item : Integer;
         {{codett|2=pascal|var item : Integer;}}
         begin
         begin
             cycle                    "execute in a loop forever"
             cycle                    <u>''"execute in a loop forever"''</u>
                 "produce an item"
                 <u>''"produce an item"''</u>
                 pass.put(item)        "pass an item to the monitor"
                 pass.put(item)        <u>''"pass an item to the monitor"''</u>
             end
             end
         end;
         end;


     "Consumer uses a buffer"
     <u>''"Consumer uses a buffer"''</u>
     consumer = process(pass : Buffer);
     consumer = process(pass : Buffer);
         var item : Integer;
         {{codett|2=pascal|var item : Integer;}}
         begin
         begin
             cycle
             cycle
                 pass.get(item);      "get an item from the monitor"
                 pass.get(item);      <u>''"get an item from the monitor"''</u>
                 "consume the item"
                 <u>''"consume the item"''</u>
             end
             end
         end;
         end;


"declare instances of the monitor, producer, and consumer"
<u>''"declare instances of the monitor, producer, and consumer"''</u>
"give the producer and consumer access to the monitor"
<u>''"give the producer and consumer access to the monitor"''</u>
var
var
   pass : Buffer;
   pass : Buffer;
Line 112: Line 112:
   cons : Consumer;
   cons : Consumer;
begin
begin
   init pass,        "initialize the monitor"
   init pass,        <u>''"initialize the monitor"''</u>
         prod(pass),  "start the producer process"
         prod(pass),  <u>''"start the producer process"''</u>
         cons(pass)  "start the consumer process"
         cons(pass)  <u>''"start the consumer process"''</u>
end.
end.
</source>
}}


==References==
==References==

Latest revision as of 20:43, 22 May 2026

Short description: Programming language
Concurrent Pascal
ParadigmsImperative, structured, concurrent
FamilyWirth Pascal
Designed byPer Brinch Hansen
First appearedApril 1974; 52 years ago (1974-04)
Typing disciplineStatic and dynamic, strong, safe
PlatformDEC PDP 11
Influenced by
ALGOL 60, Simula 67, Pascal

Concurrent Pascal is a programming language designed by Per Brinch Hansen for writing concurrent computing programs such as operating systems and real-time computing monitoring systems on shared memory computers.[1]

A separate language, Sequential Pascal, is used as the language for applications programs run by the operating systems written in Concurrent Pascal. Both languages are extensions of Niklaus Wirth's Pascal, and share a common threaded code interpreter.[2] The following describes how Concurrent Pascal differs from Wirth's Pascal.

Language description

Several constructs in Pascal were removed from Concurrent Pascal for simplicity and security:[2]

These omissions make it possible to guarantee, by a combination of compile-time checks and minimal run-time checking in the threaded-code interpreter, that a program can not damage itself or another program by addressing outside its allotted space.

Concurrent Pascal includes class, monitor, and process data types. Instances of these types are declared as variables, and initialized in an init statement.

Classes and monitors are similar: both package private variables and procedures with public procedures (called procedure entries). A class instance can be used by only one process, whereas a monitor instance may be shared by processes. Monitors provide the only mechanism for interprocess communication in a Concurrent Pascal program.

Only one process can execute within a given monitor instance at a time. A built in data type, the queue, together with operations delay and continue, are used for scheduling within monitors. Each variable of type queue can hold one process. If many processes are to be delayed in a monitor, multiple queue variables, usually organized as an array, must be provided. The single process queue variable gives a monitor full control over medium-term scheduling, but the programmer is responsible for unblocking the correct process.

A process, like a class or monitor, has local variables, procedures, and an initial statement, but has no procedure entries. The initial statement ordinarily executes forever, calling local procedures, class procedures, and monitor procedures. Processes communicate through monitor procedures. Language rules prevent deadlock by imposing a hierarchy on monitors. But nothing can prevent a monitor from erroneously forgetting to unblock a delayed process (by not calling continue) so the system can still effectively hang up through programming errors.

The configuration of processes, monitors, and classes in a Concurrent Pascal program is normally established at the start of execution, and is not changed thereafter. The communication paths between these components are established by variables passed in the init statements, since class and monitor instance variables cannot be used as procedure parameters.

Example

The following example shows the declaration of a simple monitor, and its use by two communicating processes.

type
    "Bounded buffer monitor"
    buffer = Monitor
        var
            saved         : Integer;  "saved item is an integer"
            fullq, emptyq : Queue;    "used by only two processes"
            full          : Boolean;  "true if an item is saved:"

        "Puts item in buffer"
        procedure entry put(item : Integer);
            begin
               if full then
                   delay(fullq);      "block if full"
               saved := item;         "save the item"
               full := true;          "mark as full"
               continue(emptyq)       "unblock consumer"
            end;

        "Gets item from the buffer"
        procedure entry get(var item : Integer);
            begin
               if not full then
                   delay(emptyq);     "block if empty"
               item := saved;         "get the item"
               full := false;         "mark as not full"
               continue(fullq)        "unblock producer"
            end;

        "Initialize the monitor"
        begin
            full := false
        end;

    "Producer uses a buffer"
    producer = process(pass : Buffer);
        var item : Integer;
        begin
            cycle                     "execute in a loop forever"
                "produce an item"
                pass.put(item)        "pass an item to the monitor"
            end
        end;

    "Consumer uses a buffer"
    consumer = process(pass : Buffer);
        var item : Integer;
        begin
            cycle
                pass.get(item);       "get an item from the monitor"
                "consume the item"
            end
        end;

"declare instances of the monitor, producer, and consumer"
"give the producer and consumer access to the monitor"
var
   pass : Buffer;
   prod : Producer;
   cons : Consumer;
begin
   init pass,        "initialize the monitor"
        prod(pass),  "start the producer process"
        cons(pass)   "start the consumer process"
end.

References

  1. Brinch Hansen, Per (June 1975). "The programming language Concurrent Pascal". IEEE Transactions on Software Engineering (2): 199–207. doi:10.1109/tse.1975.6312840. http://brinch-hansen.net/papers/1975a.pdf. 
  2. 2.0 2.1 Brinch Hansen, Per (1977). The Architecture of Concurrent Programs. Prentice Hall. ISBN 978-0-13-044628-2.