Concepts of Programming Languages

(Sean Pound) #1
13.6 Ada Support for Concurrency 599

13.6.2 Cooperation Synchronization


Each accept clause can have a guard attached, in the form of a when clause,
that can delay rendezvous. For example,

when not Full(Buffer) =>
accept Deposit(New_Value) do

...
end


An accept clause with a when clause is either open or closed. If the Boolean
expression of the when clause is currently true, that accept clause is called
open; if the Boolean expression is false, the accept clause is called closed.
An accept clause that does not have a guard is always open. An open accept
clause is available for rendezvous; a closed accept clause cannot rendezvous.
Suppose there are several guarded accept clauses in a select clause.
Such a select clause is usually placed in an infinite loop. The loop causes
the select clause to be executed repeatedly, with each when clause evaluated
on each repetition. Each repetition causes a list of open accept clauses to be
constructed. If exactly one of the open clauses has a nonempty queue, a mes-
sage from that queue is taken and a rendezvous takes place. If more than one
of the open accept clauses has nonempty queues, one queue is chosen non-
deterministically, a message is taken from that queue, and a rendezvous takes
place. If the queues of all open clauses are empty, the task waits for a message to
arrive at one of those accept clauses, at which time a rendezvous will occur. If
a select is executed and every accept clause is closed, a run-time exception
or error results. This possibility can be avoided either by making sure one of
the when clauses is always true or by adding an else clause in the select. An
else clause can include any sequence of statements, except an accept clause.
A select clause may have a special statement, terminate, that is selected
only when it is open and no other accept clause is open. A terminate clause,
when selected, means that the task is finished with its job but is not yet termi-
nated. Task termination is discussed later in this section.

13.6.3 Competition Synchronization


The features described so far provide for cooperation synchronization and
communication among tasks. Next, we discuss how mutually exclusive access
to shared data structures can be enforced in Ada.
If access to a data structure is to be controlled by a task, then mutually
exclusive access can be achieved by declaring the data structure within a task.
The semantics of task execution usually guarantees mutually exclusive access
to the structure, because only one accept clause in the task can be active at a
given time. The only exceptions to this occur when tasks are nested in proce-
dures or other tasks. For example, if a task that defines a shared data structure
has a nested task, that nested task can also access the shared structure, which
Free download pdf