Concurrent Pascal
- 5 min read
- 2 chapters
Related on Lably
Through Operating system, Interpreter (computing) and Function (computer programming)
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. 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:
- Variant records
- Goto statement, and labels
- Procedures as parameters
- Packed arrays
- Pointer types
- 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.
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.
Sign in to keep reading
One more chapter is free with a Lably account.
Example
The following example shows the declaration of a simple monitor, and its use by two communicating processes.
<span id="mwNg"></span><span class="n" id="mwNw">type</span> <span class="s" id="mwOA">"Bounded buffer monitor"</span> <span class="n" id="mwOQ">buffer</span> <span class="o" id="mwOg">=</span> <span class="n" id="mwOw">Monitor</span> <span class="n" id="mwPA">var</span> <span class="n" id="mwPQ">saved</span> <span class="p" id="mwPg">:</span> <span class="n" id="mwPw">Integer</span><span class="p" id="mwQA">;</span> <span class="s" id="mwQQ">"saved item is an integer"</span> <span class="n" id="mwQg">fullq</span><span class="p" id="mwQw">,</span> <span class="n" id="mwRA">emptyq</span> <span class="p" id="mwRQ">:</span> <span class="n" id="mwRg">Queue</span><span class="p" id="mwRw">;</span> <span class="s" id="mwSA">"used by only two processes"</span> <span class="n" id="mwSQ">full</span> <span class="p" id="mwSg">:</span> <span class="n" id="mwSw">Boolean</span><span class="p" id="mwTA">;</span> <span class="s" id="mwTQ">"true if an item is saved:"</span> <span class="s" id="mwTg">"Puts item in buffer"</span> <span class="n" id="mwTw">procedure</span> <span class="n" id="mwUA">entry</span> <span class="n" id="mwUQ">put</span><span class="p" id="mwUg">(</span><span class="n" id="mwUw">item</span> <span class="p" id="mwVA">:</span> <span class="n" id="mwVQ">Integer</span><span class="p" id="mwVg">);</span> <span class="n" id="mwVw">begin</span> <span class="n" id="mwWA">if</span> <span class="n" id="mwWQ">full</span> <span class="n" id="mwWg">then</span> <span class="n" id="mwWw">delay</span><span class="p" id="mwXA">(</span><span class="n" id="mwXQ">fullq</span><span class="p" id="mwXg">);</span> <span class="s" id="mwXw">"block if full"</span> <span class="n" id="mwYA">saved</span> <span class="p" id="mwYQ">:</span><span class="o" id="mwYg">=</span> <span class="n" id="mwYw">item</span><span class="p" id="mwZA">;</span> <span class="s" id="mwZQ">"save the item"</span> <span class="n" id="mwZg">full</span> <span class="p" id="mwZw">:</span><span class="o" id="mwaA">=</span> <span class="n" id="mwaQ">true</span><span class="p" id="mwag">;</span> <span class="s" id="mwaw">"mark as full"</span> <span class="n" id="mwbA">continue</span><span class="p" id="mwbQ">(</span><span class="n" id="mwbg">emptyq</span><span class="p" id="mwbw">)</span> <span class="s" id="mwcA">"unblock consumer"</span> <span class="n" id="mwcQ">end</span><span class="p" id="mwcg">;</span> <span class="s" id="mwcw">"Gets item from the buffer"</span> <span class="n" id="mwdA">procedure</span> <span class="n" id="mwdQ">entry</span> <span class="n" id="mwdg">get</span><span class="p" id="mwdw">(</span><span class="n" id="mweA">var</span> <span class="n" id="mweQ">item</span> <span class="p" id="mweg">:</span> <span class="n" id="mwew">Integer</span><span class="p" id="mwfA">);</span> <span class="n" id="mwfQ">begin</span> <span class="n" id="mwfg">if</span> <span class="n" id="mwfw">not</span> <span class="n" id="mwgA">full</span> <span class="n" id="mwgQ">then</span> <span class="n" id="mwgg">delay</span><span class="p" id="mwgw">(</span><span class="n" id="mwhA">emptyq</span><span class="p" id="mwhQ">);</span> <span class="s" id="mwhg">"block if empty"</span> <span class="n" id="mwhw">item</span> <span class="p" id="mwiA">:</span><span class="o" id="mwiQ">=</span> <span class="n" id="mwig">saved</span><span class="p" id="mwiw">;</span> <span class="s" id="mwjA">"get the item"</span> <span class="n" id="mwjQ">full</span> <span class="p" id="mwjg">:</span><span class="o" id="mwjw">=</span> <span class="n" id="mwkA">false</span><span class="p" id="mwkQ">;</span> <span class="s" id="mwkg">"mark as not full"</span> <span class="n" id="mwkw">continue</span><span class="p" id="mwlA">(</span><span class="n" id="mwlQ">fullq</span><span class="p" id="mwlg">)</span> <span class="s" id="mwlw">"unblock producer"</span> <span class="n" id="mwmA">end</span><span class="p" id="mwmQ">;</span> <span class="s" id="mwmg">"Initialize the monitor"</span> <span class="n" id="mwmw">begin</span> <span class="n" id="mwnA">full</span> <span class="p" id="mwnQ">:</span><span class="o" id="mwng">=</span> <span class="n" id="mwnw">false</span> <span class="n" id="mwoA">end</span><span class="p" id="mwoQ">;</span> <span class="s" id="mwog">"Producer uses a buffer"</span> <span class="n" id="mwow">producer</span> <span class="o" id="mwpA">=</span> <span class="n" id="mwpQ">process</span><span class="p" id="mwpg">(</span><span class="n" id="mwpw">pass</span> <span class="p" id="mwqA">:</span> <span class="n" id="mwqQ">Buffer</span><span class="p" id="mwqg">);</span> <span class="n" id="mwqw">var</span> <span class="n" id="mwrA">item</span> <span class="p" id="mwrQ">:</span> <span class="n" id="mwrg">Integer</span><span class="p" id="mwrw">;</span> <span class="n" id="mwsA">begin</span> <span class="n" id="mwsQ">cycle</span> <span class="s" id="mwsg">"execute in a loop forever"</span> <span class="s" id="mwsw">"produce an item"</span> <span class="n" id="mwtA">pass</span><span class="p" id="mwtQ">.</span><span class="n" id="mwtg">put</span><span class="p" id="mwtw">(</span><span class="n" id="mwuA">item</span><span class="p" id="mwuQ">)</span> <span class="s" id="mwug">"pass an item to the monitor"</span> <span class="n" id="mwuw">end</span> <span class="n" id="mwvA">end</span><span class="p" id="mwvQ">;</span> <span class="s" id="mwvg">"Consumer uses a buffer"</span> <span class="n" id="mwvw">consumer</span> <span class="o" id="mwwA">=</span> <span class="n" id="mwwQ">process</span><span class="p" id="mwwg">(</span><span class="n" id="mwww">pass</span> <span class="p" id="mwxA">:</span> <span class="n" id="mwxQ">Buffer</span><span class="p" id="mwxg">);</span> <span class="n" id="mwxw">var</span> <span class="n" id="mwyA">item</span> <span class="p" id="mwyQ">:</span> <span class="n" id="mwyg">Integer</span><span class="p" id="mwyw">;</span> <span class="n" id="mwzA">begin</span> <span class="n" id="mwzQ">cycle</span> <span class="n" id="mwzg">pass</span><span class="p" id="mwzw">.</span><span class="n" id="mw0A">get</span><span class="p" id="mw0Q">(</span><span class="n" id="mw0g">item</span><span class="p" id="mw0w">);</span> <span class="s" id="mw1A">"get an item from the monitor"</span> <span class="s" id="mw1Q">"consume the item"</span> <span class="n" id="mw1g">end</span> <span class="n" id="mw1w">end</span><span class="p" id="mw2A">;</span> <span class="s" id="mw2Q">"declare instances of the monitor, producer, and consumer"</span> <span class="s" id="mw2g">"give the producer and consumer access to the monitor"</span> <span class="n" id="mw2w">var</span> <span class="n" id="mw3A">pass</span> <span class="p" id="mw3Q">:</span> <span class="n" id="mw3g">Buffer</span><span class="p" id="mw3w">;</span> <span class="n" id="mw4A">prod</span> <span class="p" id="mw4Q">:</span> <span class="n" id="mw4g">Producer</span><span class="p" id="mw4w">;</span> <span class="n" id="mw5A">cons</span> <span class="p" id="mw5Q">:</span> <span class="n" id="mw5g">Consumer</span><span class="p" id="mw5w">;</span> <span class="n" id="mw6A">begin</span> <span class="n" id="mw6Q">init</span> <span class="n" id="mw6g">pass</span><span class="p" id="mw6w">,</span> <span class="s" id="mw7A">"initialize the monitor"</span> <span class="n" id="mw7Q">prod</span><span class="p" id="mw7g">(</span><span class="n" id="mw7w">pass</span><span class="p" id="mw8A">),</span> <span class="s" id="mw8Q">"start the producer process"</span> <span class="n" id="mw8g">cons</span><span class="p" id="mw8w">(</span><span class="n" id="mw9A">pass</span><span class="p" id="mw9Q">)</span> <span class="s" id="mw9g">"start the consumer process"</span> <span class="n" id="mw9w">end</span><span class="p" id="mw-A">.</span>

