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

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

!standard 11.6(5)          06-12-14 AI05-0030-1/00
!class Amendment 06-03-21
!status work item 06-03-21
!status received 06-03-03
!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.

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


Questions? Ask the ACAA Technical Agent