I am currently trying to plunge into the details of ATC (asynchronous transfer
of control) in Ada. Please consider the following scenario:
Given a task, T, and a protected object, P (which owns an entry, E), let T
execute the following ATC statement:
select
P.E(...);
then abort
-- sequence of statements to be aborted upon completion of P.E
end select;
If the entry call is queued, then the abortable part is executed. If, then, the
entry call can be accepted, the abortable part *and* the triggering statement
are executed in parallel. Since T's thread of control is associated with the
abortable part, another thread of control must be employed to execute P.E
Accordingly, the Ada Standard allows that ``an implementation may perform the
sequence of steps of a protected action using any thread of control; it need
not be that of the task that started the protected action.'' (Section~9.5.3)
Thus, for example, the thread of control of the main program or that of a
client task engaged in a rendezvous could be used instead. There is, however,
a question as to what should happen if all other existing threads of control
are in use. Does ``... any thread of control ...'' mean that an implementation
is allowed to introduce a new thread of control that executes P.E? And, if so,
which entity in our sample program is this new thread of control considered to
be associated with? Or is it deemed to be anonymous (since it will cease to
exist when P.E completes)? Of course, since nested ATC is possible, the
problem can be generalized to any (positive) number of threads of control.
I am at the end of my wit and would be grateful if someone could help me
with this problem (or debunk my misconception).
Thanks in advance,
Frank Ecke, fra...@minet.uni-jena.de
Frank> I am currently trying to plunge into the details of ATC
Frank> (asynchronous transfer of control) in Ada.
Since you're interested in a technical answer, why don't you just read
GNAT runtime sources to see how it has been implemented in this compiler?
Frank> If the entry call is queued, then the abortable part is
Frank> executed. If, then, the entry call can be accepted, the
Frank> abortable part *and* the triggering statement are executed in
Frank> parallel.
There is no obligation to execute those two sequences in parallel. For
example, the runtime system will be able to notice that the triggering
statement can now be executed, and redirect the thread of control used
for the abortable part so that it executes the triggering statement
(after of course all the finalization actions have been executed). The
result is that, with only one thread of control, the abortable part
has been aborted while the triggering statement has been accepted.
Sam
--
Samuel Tardieu -- s...@ada.eu.org
I don't believe that this can happen. The thread for the client task P,
as it is also involved in the rendezvous, can't be otherwise in use and
so will always be available.
--
Mark Biggar
mark.a...@lmco.com
This is, of course, always a resort, but I wanted to try the manual first.
>
>There is no obligation to execute those two sequences in parallel.
>
Indeed, there is no such obligation. But there is the possibility.
>
>For
>example, the runtime system will be able to notice that the triggering
>statement can now be executed, and redirect the thread of control used
>for the abortable part so that it executes the triggering statement
>(after of course all the finalization actions have been executed).The
>result is that, with only one thread of control, the abortable part
>has been aborted while the triggering statement has been accepted.
>
It is not the acceptance but the completion of the triggering statement that
causes the abortable part to be aborted.
Hence, while the trigger is beeing executed, the abortable part cannot be
completed, finalized, and left due to ATC.
I posed my problem to ada-c...@sw-eng.falls-church.va.us and the co-author
of the Ada Standard, Robert A. Duff, replied:
Yes, the implementation can create extra anonymous threads of control,
if it likes. For example, the abortable part could be put inside a
separate task. C.7.1(17) is one rule that helps allow that.
However, a simpler (and efficient) run-time model is to have entry
bodies run by whichever task caused the barrier to become True. This
works whether or not the entry call is part of an ATC. In your example,
suppose P looks like:
protected P is
entry E;
procedure Something;
...
end;
and procedure Something causes E's barrier to become True. Whichever
task is calling Something will then (before releasing the lock on P)
check the barrier(s), notice that E should happen, and execute E's body.
It will do that repeatedly, until all barriers are False. Depending on
what the body of P looks like, a single call to Sometime might cause E's
body to be executed several times, for several callers.
[snip]
- Bob
It is not true that these are executed in parallel. RM 9.7.4:6 says
that the abortable_part is never started if the entry call is accepted.
The abortable_part is only executed if (or when) the entry becomes
queued (or requeued-with-abort). No need for an extra thread.
> abortable part, another thread of control must be employed to execute P.E
> Accordingly, the Ada Standard allows that ``an implementation may perform the
> sequence of steps of a protected action using any thread of control; it need
> not be that of the task that started the protected action.'' (Section~9.5.3)
> Thus, for example, the thread of control of the main program or that of a
> client task engaged in a rendezvous could be used instead. There is, however,
> a question as to what should happen if all other existing threads of control
> are in use. Does ``... any thread of control ...'' mean that an implementation
> is allowed to introduce a new thread of control that executes P.E? And, if so,
> which entity in our sample program is this new thread of control considered to
> be associated with? Or is it deemed to be anonymous (since it will cease to
> exist when P.E completes)? Of course, since nested ATC is possible, the
> problem can be generalized to any (positive) number of threads of control.
>
> I am at the end of my wit and would be grateful if someone could help me
> with this problem (or debunk my misconception).
>
> Thanks in advance,
>
> Frank Ecke, fra...@minet.uni-jena.de
-Brian Nettleton
I agree; ATC is a subtle topic and I did not intend to praise it.
Actually, the phrase ``Holy Grail of Ada Tasking'' was meant ironically in
the sense of ``if you want to live in bliss with Ada Tasking, don't touch that
stuff!'' Sorry for introducing this ambiguity!
The point is that I am currently writing a project alfa core in which I am
investigating and comparing the concurrency features of Ada, CHILL, and Java.
This, however, requires me to scrutinize each and every aspect of concurrency
in these languages.
Frank
>
>the sense of ``if you want to live in bliss with Ada Tasking, don't touch that
>stuff!''
>
``... don't touch that ATC stuff!'', of course
Frank
<snip>
> The point is that I am currently writing a project alfa core in which I
am
>investigating and comparing the concurrency features of Ada, CHILL, and
Java.
>This, however, requires me to scrutinize each and every aspect of
concurrency
>in these languages.
In that case, if you haven't already done so, I strongly suggest you have an
extended look at Burns and Wellings' book titled Concurrency In Ada, second
edition (1998), Cambridge University Press, ISBN 0-521-62911-X. Every
aspect of the Ada 95 tasking model is covered in great detail.