Version 1.5 of ais/ai-00327.txt

Unformatted version of ais/ai-00327.txt version 1.5
Other versions for file ais/ai-00327.txt

!standard D.03 (00)          03-08-11 AI95-00327/02
!class amendment 03-06-05
!status work item 03-06-05
!status received 03-06-05
!priority Medium
!difficulty Medium
!subject Dynamic ceiling priorities
!summary
An implementation of dynamic ceiling priorities is proposed. The ceiling priority of a protected object (PO) would be dynamically changed by giving access to a new attribute of a protected object.
With this mechanisms, the ceiling may be changed from a valid priority, according to the ceiling locking protocol. This is the only way to ensure a consistent ceiling change without the need for a lock to protect the ceiling change. An example is provided to show how to use this feature. The proposal is the result of considerable discussion at IRTAW and represents the most effect solution (of the very many that are possible).
A prototype implementation by Jorge Real concludes that the overheads of this feature is small and not distributed.
!problem
In Ada, the ceiling priority of a PO is static and thus it can only be assigned once, by means of pragma Priority, at PO creation time. In contrast with that, tasks' priorities are dynamic. The ability to dynamically changing ceiling priorities is specially useful in:
- multi-moded systems, - systems scheduled with dynamic priorities and - dynamically adapting library units containing POs.
For multi-moded systems, a common workaround is to use the so called "ceiling of ceilings", i.e. the highest ceiling that PO will have across all operating modes. Unfortunately, this approach is not elegant and may have a considerable impact on blocking times: by using the ceiling of ceilings, a task running in a particular mode can be blocked by another one due to the ceiling priority of a PO being higher in another operating mode. It can be the case that the priority assignment for that particular mode would produce a lower ceiling for the PO, thus resulting in a null blocking time for some tasks.
Overall, the ceiling of ceilings reduces the feasibility of the task set.
Similar considerations hold for the other two situations (dynamic priority systems and adapting libraries).
!proposal
A new attribute of a protected object is defined:
P'Priority: Yields a variable component of protected object P of type System.Any_Priority, which denotes the priority of P. Use of this attribute is allowed only inside a protected body.
Note if Locking_Policy Ceiling_Locking is specified then P'Priority denotes the ceiling priority of P.
The caller to the protected operation enclosing use of the attribute must be executing, at most, at the current ceiling priority of the PO. Otherwise, Program_Error should be raised to the caller, as is the rule for accessing a PO (ARM D.5-11). In other words, the ceiling change must follow the ceiling locking protocol. This approach eliminates the need for an additional lock on the PO.
The change of priority by means of an assignment to the attribute takes place at the end of the enclosing protected action.
According to this semantics, a read of 'Priority after an assignment to 'Priority will return the old value.
It is a bounded error to lower the ceiling priority while there are tasks queued on an entry with higher priorities. In this case Program_Error is raised in the queued tasks, or the queued tasks execute with the lower ceiling priority when they become unblocked, or both, or neither (c.f. Dynamic Priorities D.5(11)).
If Ceiling_Locking is not in effect and no priority has been set then the attribute returns an implementation defined value.
A new restriction, No_Dynamic_Ceilings, is introduced and added to the Ravenscar Profile.
!wording
!example
A simple example on how to use the proposed features is given in this section.
protected type My_Protected is pragma Priority(Some_Initial_Value : Any_Priority); procedure Set_My_Ceiling(Pr: in Any_Priority); -- other protected procedures, functions and/or entries end My_Protected;
protected body My_Protected is procedure Set_My_Ceiling(Pr : in Any_Priority) is begin -- Code before setting the ceiling My_Protected'Priority := Pr; -- Code after setting the ceiling -- The new ceiling does not take effect -- until the end of this procedure end Set_My_Ceiling;
-- Rest of bodies
end My_Protected;
PO: My_Protected; -- Instantiation of the PO
!discussion
Is it necessary for a read of 'Priority (after a write) to return the old value?
!ACATS test
!appendix

From: Alan Burns
Sent: Thursday, June 5, 2003  5:02 AM

The Real-Time workshop has discussed at some length the
incorporation of dynamic ceiling for POs. A number of
solution have been proposed and discussed. In the attached
AI is the concensus proposal which I offer as a new AI.

[Editor's note: This is version /01 of the AI.]

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

From: Alan Burns
Sent: Monday, August 11, 2003  8:14 AM

Attached is new version of AI 327 (dynamic
priorities for POs).

I have followed the suggestions of Tucker (and the
minutes). If anyone has time to look at the details
of the ammended proposal and agree I could produce
the wording section before the next meeting.

Version 1 of this AI contains detailed discussions on the motivation
behind the proposal and further examples (for an earlier version of
the feature).

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

From: Randy Brukardt
Sent: Wednesday, September 10, 2003 11:12 PM

I've looked at this AI. I think the general idea is what was discussed at the
meeting. A couple of specific comments:

1) Is it necessary to return the 'old' value of the priority? I recall Tucker
wanting to avoid that, as it increases the overhead of a protected object (you
have to have two priority values). Since no other task can read it anyway (to
do so would violate the PO locking rules), so all you're doing is hiding a
change the operation made from itself. That seems silly.

2) I think that some of the motivation for allowing this only during a
protected operation needs to be retained in the discussion. Older versions of
AIs are for historical reference only, and shouldn't be depended on to provide
important information. OTOH, I don't really want to see 5 pages of diagrams,
either.

3) The bounded error text says Program_Error is raised (fine) or queued tasks
execute with the lower priority (fine) or both (??) or neither (??). "Neither"
is weird wording; I'd probably say what was actually meant (queued tasks
execute with the original priority - at least, I think that was what was
meant). And "both" is weirder: if Program_Error is raised, how can it be
executing in the PO at all? Any handler would be in the context of the caller,
and would use that priority, I hope.

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

From: Alan Burns
Sent: Thursday, September 11, 2003 11:47 AM

> I've looked at this AI. I think the general idea is what was discussed at
> the meeting. A couple of specific comments:

Thanks

>
> 1) Is it necessary to return the 'old' value of the priority? I recall
> Tucker wanting to avoid that, as it increases the overhead of a protected
> object (you have to have two priority values). Since no other task can
> read
> it anyway (to do so would violate the PO locking rules), so all you're
> doing
> is hiding a change the operation made from itself. That seems silly.

OK, will change to reflect this - after the Real-Time Workshop

>
> 2) I think that some of the motivation for allowing this only during a
> protected operation needs to be retained in the discussion. Older versions
> of AIs are for historical reference only, and shouldn't be depended on to
> provide important information. OTOH, I don't really want to see 5 pages of
> diagrams, either.

OK, will bring some of this text back

>
> 3) The bounded error text says Program_Error is raised (fine) or queued
> tasks execute with the lower priority (fine) or both (??) or neither (??).
> "Neither" is weird wording; I'd probably say what was actually meant
> (queued
> tasks execute with the original priority - at least, I think that was what
> was meant). And "both" is weirder: if Program_Error is raised, how can it
> be
> executing in the PO at all? Any handler would be in the context of the
> caller, and would use that priority, I hope.

This is the same case as dynamic priorities for tasks, and these
words are exactly those currently used in the LRM (D.5.11) - ie
'neither' is your word, weird or not.

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

From: Randy Brukardt
Sent: Thursday, September 11, 2003  4:27 PM

> This is the same case as dynamic priorities for tasks, and these
> words are exactly those currently used in the LRM (D.5.11) - ie
>'neither' is your word, weird or not.

Two wrongs don't make a right. (And it certainly isn't my word; I didn't have
anything to do with writing the Ada 95 standard, and certainly not Annex D.)

It certainly is fair to copy existing wording, but I still think we need to
look at it, because it is very confusing the way it is.

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

Questions? Ask the ACAA Technical Agent