[comp.lang.ada] Asynchronous entry call proposal

stt@inmet (04/21/89)

The recent International Workshop on Real-Time Ada Issues
debated various alternatives for providing
asynchronous transfer of control in Ada.

Here is a new proposal using entry calls
rather than exceptions to provide the asynchronous
transfer of control.  This proposal has also been submitted
to the Ada9X revision-request mailbox.
---------

To satisfy perceived requirements for asynchronous transfer
of control [Ada letters special edition, Vol VII,7 Fall 88 --
2nd Int'l Wkshp on RT Ada Issues -- hereafter IWRT2], we propose the provision
for an asynchronous entry call/selective wait construct.

There are many situations where it is useful to terminate
one sort of processing and continue processing in
a new place, based on an external/terminal interrupt, mode switch,
etc.   Currently interrupts may be bound to task entries, but
there is no action which can be taken within the
corresponding accept body to terminate ongoing
processing other than the abort statement.  
It was felt by most of the participants of [IWRT2] that
this approach was unacceptably expensive and inadequately
controllable.  

The approach most widely recommended
in [IWRT2] was asynchronous exceptions.  However, many
problems were identified with this approach, requiring
an number of new concepts such as enabling/disabling exceptions,
new classes of exceptions, queuing rules, etc.  We feel
that an asynchronous entry call/selective wait construct solves
many of these problems while introducing fewer new
concepts into the language.

Here is the proposed new selective wait construct:

select
   select_alternative
{ or 
    select_alternative}
and
   sequence_of_statements
end select;

The semantics of this construct are that
normal processing is performed on the select alternative guards
to determine which should be "open."  Selection of one such
open alternative takes place immediately if a rendezvous is
possible, or if a delay alternative of less than or equal to zero seconds
is open.  Otherwise, the sequence_of_statements begin execution.
If the sequence_of_statements completes execution,
then the select alternatives are closed.

If prior to completion of the sequence_of_statements and outside of
any nested rendezvous (either accept or entry call),
a delay alternative has expired, or an open accept alternative has a caller,
then the sequence_of_statements is abandoned, 
and an asynchronous transfer
of control takes place to the appropriate open select alternative.
This abandonment takes place no later than the next synchronization
point, but it is the intent that any ongoing computation 
(outside of a rendezvous) be preempted.

If the same entry is made open via a nested selective wait
or accept statement, then the inner construct takes precedence.

Nested rendezvous are protected from preemption to
prevent corruption of protected data structures and
undesirable side effects in the calling task.
Note however, that within a nested accept it is
possible to further nest an asynchronous selective wait
thereby again allowing for nested asynchronous transfer of control.

Here are some examples of use:

    loop -- Main command loop for a command interpreter
        select
            accept Terminal_Interrupt;
	    Put_Line("Interrupted");
        and
	    -- This will be abandoned upon terminal interrupt
	    Put_Line("-> ");
	    Get_Line(Command, Last);
	    Process_Command(Command(1..Last));
        end select;
    end loop;

---------------------------
    select  -- Perform time-limited calculation
	delay 5.0;
	Put_Line("Calculation does not converge");
    and
	-- This calculation should finish in 5.0 seconds
        -- if not, it is assumed to diverge
        Horribly_Complicated_Recursive_Function(X, Y);
    end select;

------------------------------

    S. Tucker Taft
    Intermetrics, Inc.
    733 Concord Avenue
    Cambridge, MA  02138
    617-661-1840
    stt@inmet.inmet.com / uunet!inmet!stt

billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe,2847,) (04/22/89)

From article <124000037@inmet>, by stt@inmet:
> Here is the proposed new selective wait construct:
> 
> select
>    select_alternative
> { or 
>     select_alternative}
> and
>    sequence_of_statements
> end select;
> 
> The semantics of this construct are that normal processing is performed 
> on the select alternative guards to determine which should be "open."  
> Selection of one such open alternative takes place immediately if a 
> rendezvous is possible, or if a delay alternative of less than or equal 
> to zero seconds is open.  Otherwise, the sequence_of_statements begin 
> execution.  If the sequence_of_statements completes execution,
> then the select alternatives are closed.

    So far, what we have is precisely identical to the existing construct:

      select
         select_alternative
    { or 
         select_alternative }
    [ else
         sequence_of_statements ]
      end select;
   
> If prior to completion of the sequence_of_statements and outside of
> any nested rendezvous (either accept or entry call), a delay alternative 
> has expired, or an open accept alternative has a caller, then the 
> sequence_of_statements is abandoned, and an asynchronous transfer
> of control takes place to the appropriate open select alternative.
> This abandonment takes place no later than the next synchronization
> point, but it is the intent that any ongoing computation 
> (outside of a rendezvous) be preempted.  [...]  Example of use:
>
>     select  -- Perform time-limited calculation
> 	delay 5.0;
> 	Put_Line("Calculation does not converge");
>     and
> 	-- This calculation should finish in 5.0 seconds
>         -- if not, it is assumed to diverge
>         Horribly_Complicated_Recursive_Function(X, Y);
>     end select;

   This can be accomplished now by wrapping the function
   up in a task, activating it, delaying 5.0, and then 
   killing it off if it hasn't completed...

   > It was felt by most of the participants of [IWRT2] that
   > this approach was unacceptably expensive and inadequately
   > controllable.  

   But this will essentially have to be done anyway; it seems
   that this proposal would simply move the abort of the 
   sequence_of_statements "behind the scenes".  What improvement
   is being made which could not be applied more directly to simply 
   making the existing abort statement deliver better performance?


   Bill Wolfe, wtwolfe@hubcap.clemson.edu

   P.S. I also didn't see any discussion of how the proposed
        "abortable else" would interact with the existing,
        non-abortable else section...  what if the programmer
        supplied both?  Or are you making them mutually exclusive?
 

taft@ajpo.sei.cmu.edu (Tucker Taft) (05/05/89)

Here is a reply which never quite made it to the net:
/* Written 11:54 am  May  1, 1989 by stt@inmet in inmet:comp.lang.ada */
One significant difference between the Asynchronous
Entry Call proposal and "abort" is that the asnychronous
transfer of control is inhibited inside nested accepts.
Normally, abort is only inhibited for a caller inside
a rendezvous.  The acceptor may be aborted within a rendezvous,
causing the unsuspecting caller to get a Tasking_Error.

Note also, that to use the "abort" approach, the
task to be aborted must be visible to the
selective wait, and therefore potentially visible
to other external tasks.  With this proposal, the computation
which will be terminated is nested within the
selective wait, and designed so that no tasks external
to the computation have visibility on it,
and therefore no such external tasks would be unduly affected
by the termination of the computation.

Finally, the proposed syntax makes it very clear
that the "and" part is intended to support premature
termination, as opposed to "abort" where the normal
presumption is that a task will not be aborted except
under extraordinary circumstances, or as the Ada RM puts it:
"an abort statement should be used only in extremely severe
situations..."
In other words, this is intended to be a "structured premature
termination" construct, whereas the "abort" is the analogue of the
"goto," allowing unstructured termination, invocable by
any task having visibility on the victim.

The BNF was intended to indicate that an "else" part
was mutually exclusive with an "and" part in this
proposed selective wait.

Tucker Taft (stt@inmet.inmet.com)
Intermetrics, Inc.
/* End of text from inmet:comp.lang.ada */