Version 1.3 of ai05s/ai05-0030-1.txt

Unformatted version of ai05s/ai05-0030-1.txt version 1.3
Other versions for file ai05s/ai05-0030-1.txt

!standard 9.5.4(3)          06-12-14 AI05-0030-1/00
!class Amendment 06-10-13
!status work item 06-10-13
!status received 06-10-13
!priority Medium
!difficulty medium
!subject Requeue on sychronized interfaces
!summary
(See proposal.)
!problem
** See Alan's mail **
!proposal
[Allow requeues on primitive procedures of synchronized interfaces. For a requeue on a real procedure (not an entry), raise Program_Error? Just call the procedure? Fall over dead? ;-)]
!wording
(** TBD **)
!discussion
** TBD **
!example
** Hopefully Alan will send one someday **
!ACATS test
Create an ACATS test to check that the above changes work.
!appendix

From: Alan Burns
Sent: Friday, October 13, 2006  5:54 AM

Andy and I have been developing some real-time 'patters' for common
idioms; for example periodic tasks with deadline overrun detection and
budget rationing. We can do this in quite an abstract way by the use of
task, protected and synchronized interfaces. However, we have come
across a couple of situations where we want to requeue to another entity
and the inability to 'requeue to a procedure' has impacted on the expressive
power of what we are trying to do.

When task, protected and synchronized interfaces were introduced the
provision was made to be able to make a timed call on an interface 
procedure.
I believe it was a simple omission for Ada 2005 to fail to allow requeues on
interface procedures. Is there anyway of putting this omission right?

The language rules would seem to be straightforward - if the 'procedure'
was not implemented as an entry then an exception should be raised
at the point of the requeue.

To give a simple example:
Given:

type Server is synchronized interface;
procedure Register(S: in out Server) is abstract;
type Any_Server is access all Server'Class;

We now define:
protected type X(S : Any_Server) is
 entry Y;
end X;

protected body X is
 entry Y when True is
 begin
      requeue S.Register;
 end
end X;

You know that S must be a task or a PO.
Consequently, this would seem to us to be
a valid thing you would want to do (ie requeue
to S.Register).

****************************************************************

From: Pascal Leroy
Sent: Friday, October 13, 2006 6:26 AM

> The language rules would seem to be straightforward - if the 
> 'procedure' was not implemented as an entry then an exception 
> should be raised at the point of the requeue.

Is there any reason why you want to raise an exception in this case?  In
all the other cases where some "procedure" may or may not be an entry we
defined some reasonable semantics that doesn't involve exceptions.  Why
would requeue be different?  My concern is that users would have to handle
predefined exceptions in order to prevent their code from dying if the
procedure is not implemented by an entry.  This doesn't seem right.

****************************************************************

From: Tucker Taft
Sent: Friday, October 13, 2006  7:25 AM

One of the issues with requeue is that the semantics are
relatively tightly tied to there actually being a queue
on which to place the entry call, since the requeue may
be executed by an entry body that is being run on some
"convenient" thread.  You probably wouldn't want to
allow the requeue to involve invoking synchronously
an arbitrarily complicated procedure with possibly
multiple nested blocking actions.  That works OK
at an original call point, but for a requeue, it
would not work in any straightforward way.  Requeue
pretty explicitly specifies the presence of a queue,
and if there isn't one, raising an exception seems
like about the only recourse.

****************************************************************

From: Alan Burns
Sent: Friday, October 13, 2006  7:57 AM

Yes this was our conclusion, fundamental to requeue is that control
passes from the current context. When the entry is completed, control
does not return to the point of the requeue, so executing the procedure and
returning does not seem right. An exception seems like the right action
as tuck says

****************************************************************

From: Pascal Leroy
Sent: Friday, October 13, 2006  7:44 AM

I understand, but given that (1) we are not capable of defining proper
semantics in the case where the procedure is not an entry and (2) we have
no way to specify on the interface that the procedure has to be
implemented by an entry, I conclude that the entire idea is a bad
violation of the Substitution Principle and that it is a good thing that
requeue-through-interfaces are disallowed.

****************************************************************

From: Tucker Taft
Sent: Friday, October 13, 2006  8:56 AM

I was concerned about the same thing, and so I was very
interested in seeing realistic examples.  I believe that
Alan and Andy came up with several.  Once you start using
polymorphism with tasking, it seems inevitable that if
you do an "external" requeue, you will want to be able
to do it through an interface.

Perhaps we need some way of requiring
a procedure to be implemented by an entry?
We could make it an optional pragma (analogous to pragma
Convention) which if absent, leaves open the possibility
of a run-time exception, but if present, ensures that no
run-time exception would occur at the point of requeue.
Adding new syntax is of course a possibility, but then
this no longer looks like a "binding interpretation"
style of AI, but rather clearly an amendment.

Alternatively, we figure out a way to implement this
by treating a procedure as equivalent to an entry with
a "true" barrier, and have a pseudo "queue" created
as needed upon invocation of the requeue.  This latter
approach seems to require more implementation work
and more tricky wording.

My conclusion was that there *was* an oversight in this
area, and the "simple" solution of raising an exception
would be sufficient for a quick fix, but that next
time we get into "amendment" mode, we could work out a
more sophisticated model, while remaining effectively
compatible with this simple exception-raising approach.
Admittedly not ideal, but I hate to "orphan" requeue
as we move into a polymorphic synchronization world.

****************************************************************

From: Pascal Leroy
Sent: Friday, October 13, 2006  9:49 AM

> I was concerned about the same thing, and so I was very 
> interested in seeing realistic examples.  I believe that Alan 
> and Andy came up with several.  Once you start using 
> polymorphism with tasking, it seems inevitable that if you do 
> an "external" requeue, you will want to be able to do it 
> through an interface.

I would certainly like to see realistic examples, if Alan is willing to
share them with the rest of us.

> Perhaps we need some way of requiring
> a procedure to be implemented by an entry?

That might be a nice extension in the future, but I think we first want to
see synchronized interfaces used in real life.  And we are not in
amendment mode anymore.

> Alternatively, we figure out a way to implement this
> by treating a procedure as equivalent to an entry with
> a "true" barrier, and have a pseudo "queue" created
> as needed upon invocation of the requeue.  This latter
> approach seems to require more implementation work
> and more tricky wording.

I still don't understand what would be wrong with the following: if the
procedure is not an entry, the requeue statement calls the procedure, and
when the procedure returns it immediately leaves the enclosing accept
statement or entry body.  True, the procedure called that way could do all
sorts of nasty things like potentially blocking operations, but this is a
general danger with dispatching calls.  At least with such a scheme the
user could give a reasonable semantics to the call if they so desire (or
they could raise an exception in the classes that don't implement the
procedure as an entry).

****************************************************************

From: Tucker Taft
Sent: Friday, October 13, 2006  9:58 AM

Another way to view this requeue restriction would be to think of it as
similar to the rules that forbid calling a potentially
blocking operation from inside a protected operation.  I.e.:

   If you *call* a procedure through a synchronized
   interface from inside a protected operation, if
   the procedure turns out to be implemented (directly
   or indirectly) via an entry, then that would be
   violating the no-potentially-blocking rules.  If you
   *requeue* on a procedure through a synchronized
   interface then you would get an exception if it
   is *not* an implemented by an entry.

There seems a pretty close analogy, where you have
to have some knowledge of how the procedure of
a synchronized interface is implemented to know whether
to call or to requeue.  If you are wrong in either
way, you could get Program_Error at the point of the
call/requeue.

****************************************************************

From: Tucker Taft
Sent: Friday, October 13, 2006  10:05 AM

> I still don't understand what would be wrong with the following: if the
> procedure is not an entry, the requeue statement calls the procedure, and
> when the procedure returns it immediately leaves the enclosing accept
> statement or entry body.  True, the procedure called that way could do all
> sorts of nasty things like potentially blocking operations, but this is a
> general danger with dispatching calls.  At least with such a scheme the
> user could give a reasonable semantics to the call if they so desire (or
> they could raise an exception in the classes that don't implement the
> procedure as an entry).

Those semantics don't seem too bad to me.  As you say, if the
procedure involves a blocking operation, you are in trouble
and will possibly get a Program_Error
If it doesn't, then you are OK.

But I also think my message that crossed in the
e-mail with yours provides some justification
for raising Program_Error at the requeue point.

I could go either way.  If we do want it to "work"
when requeuing on a procedure, I agree yours is the
more straightforward implementation model.

****************************************************************

From: Alan Burns
Sent: Friday, October 13, 2006 11:49 AM

Andy and I can produce some examples - but not immediately
as I am about to go off traveling for a week, by which time
I'm sure Pascal and Tuck will have agreed on the right language
model! We were concerned with the implementation overhead
of anything other than raising an exception.

****************************************************************

From: Robert A. Duff
Sent: Friday, October 13, 2006  3:41 AM

A protected procedure is a lot like an entry with an always-True barrier.
Therefore, I agree with the following:

> I still don't understand what would be wrong with the following: if the
> procedure is not an entry, the requeue statement calls the procedure, and
> when the procedure returns it immediately leaves the enclosing accept
> statement or entry body.

****************************************************************

From: Randy Brukardt
Sent: Friday, October 13, 2006  6:25 PM

Alan Burns wrote:

...
> When task, protected and synchronized interfaces were introduced the
> provision was made to be able to make a timed call on an interface
> procedure. I believe it was a simple omission for Ada 2005 to fail
> to allow requeues on interface procedures. Is there anyway of putting
> this omission right?

I don't want to comment on whether or not it is a good idea, but this was
not "a simple omission". We specifically considered whether we wanted to
allow requeue at the Paris meeting (Feb. 2005), and rejected the idea. The
minutes of that meeting say (under AI-397):

"Steve Baird asks if you can requeue on a synchronized procedure. No, we
don't allow that, because the synchronized procedure doesn't necessarily
denote an entry. And what such a requeue would do if the procedure wasn't
an entry is rather unclear."

(My memory was that there was more issues beyond the one recorded, but since
I don't remember any details, at this point that would be just FUD.)

I can imagine that new information could make it worthwhile to make a
different decision on requeue, but not having it was certainly *not* an
omission. It was completely intentional. As such, I think we would have to
classify this as an Amendment (I don't think "we changed our mind" is a
legitimate reason to classify something as a bug)!

Personally, I think requeueing to a procedure makes no sense at all, and
thus Program_Error seems to be appropriate. It is already devilishly hard to
implement (external) requeue, and this will be worse -- I don't see much
reason to try hard to make useless cases work.

I'd like to see a real example, too. Not that I doubt that Alan has one, but
it would be valuable to get it on the record and try to judge its
importance. Especially if we want to lie about this being a bug -- in that
case, I think it had better be quite important.

****************************************************************

From: Alan Burns
Sent: Tuesday, November 14, 2006  2:32 AM

I note the following on the agenda.

>Requeue on synchronized interfaces [AI not made yet.]

After I raised this point about requeue on interfaces Randy noted that 
this was not an 'omission' but a clear decision at some meeting or other
not to allow requeue. Hence I assume the issue is closed. However if the
ARG is at least open to consider this topic I will produce an AI for a
future meeting.

If the current meeting has time to at least decide if such an AI is 'in 
scope' I would appreciate it.

****************************************************************

From: John Barnes
Sent: Wednesday, November 22, 2006  2:01 AM

It was suggested at the meeting last weekend that the topic should be
considerd by the next IRTAW in Vermont and then reported back to the ARG in
Geneva.

****************************************************************

From: Alan Burns
Sent: Wednesday, May 2, 2007  3:49 AM

Re AI05-0030 - requeue on synchronized interfaces

I understand that the ARG asked the IRTAW to look at the
issue of allowing, in some form, requeue via procedures
defined in synchronized (and task and protected) interfaces.

The workshop discussed this at length, following a position
paper from Wellings and Burns that contained an example of
usage (I can email this paper to the ARG if you wish).
The workshop adopted the following position

1. That requeue through synchronized interfaces is a useful primitive and
should be supported in Ada. It furthers the integration of the
OO and concurrency features of the language.

2. That requeue and the other (existing) 2005 features such as making
a timed entry call on a synchronized interface procedure should be
dealt with in the same way.

3. That a static scheme in which a procedure is identified as
being 'implemented as an entry' is an acceptable solution.
If the term 'entry' cannot be introduced into an interface
definition then the use of a pragma to identify a procedure that must be
implemented as an entry is a possible scheme.

4. That it is possible to define the semantics for requeue to a
procedure but that the implementation cost of such a model
on existing run-times be investigated.

In conclusion, the workshop favoured a static approach that only
allowed requeue on procedures implemented as entries (point 3)
and that the definition of timed entry calls etc should be changed
to be similarly restricted. If however the existing definitions were
to remain then requeue should be allowed on 'entries' and 'procedures'
if the implementation (run-time) overhead is not prohibitive.

****************************************************************

From: Pascal Leroy
Sent: Wednesday, May 2, 2007  5:00 AM

> The workshop discussed this at length, following a position 
> paper from Wellings and Burns that contained an example of 
> usage (I can email this paper to the ARG if you wish).

This would be a useful thing to do, Alan.  At the last meeting we briefly
discussed this topic, but since nobody other than Tuck had seen an example
of usage, it was hard to make progress.

> In conclusion, the workshop favoured a static approach that 
> only allowed requeue on procedures implemented as entries 
> (point 3) and that the definition of timed entry calls etc 
> should be changed to be similarly restricted.

Keep in mind that we are no longer in Amendment mode, and that we have to
worry about compatibility.  We can compromise compatibility to fix
language holes, but we are no allowed to just change our mind.  If you
want to restrict timed entry calls, you'll have make a strong case that it
was a blunder to allow them in the first place.  

> If however the 
> existing definitions were to remain then requeue should be 
> allowed on 'entries' and 'procedures' if the implementation 
> (run-time) overhead is not prohibitive.

It would be good to explain to us what the semantics should be if we allow
requeueing to a procedure.

I suppose that you are going to update the AI and answer these questions
and more, right?

****************************************************************

From: Alan Burns
Sent: Friday, May 4, 2007  3:03 AM

Attached is the paper from Andy and I on requeue. It does discuss what the semantics
for requeue to a procedure could be (there will also be more detail in the IRTAW
session summary to be published soon). [Editor's note: the paper can be found in the
ARG grab bag at http://www.ada-auth.org/ai-files/grab_bag/requeue.pdf.]

As the IRTAW is not the ARG, it felt it should express the ideal situation (ie requeue and
timed entry calls dealt with in an identical way), the ARG can/will obvious see what this
means in terms of the Ada 'process'.

You asked me to update the AI - as we do not have a specific recommendation how should
this be done? Shall I just add a report?

****************************************************************

From: Randy Brukardt
Sent: Friday, May 4, 2007  8:03 PM

It's ultimately Pascal's call, but I think you should write up a *complete* proposal
of what you think the ideal solution is. (Complete means including at least a
determination of where wording changes will be needed.) Then we (the ARG) can
decide if/when it can be implemented and any modifications. (In particular, if
it is too large for a Corrigendum change and if it is too incompatible.)

****************************************************************

Questions? Ask the ACAA Technical Agent