CVS difference for ais/ai-00327.txt
--- ais/ai-00327.txt 2003/09/30 02:01:13 1.6
+++ ais/ai-00327.txt 2003/11/25 02:24:10 1.7
@@ -1,4 +1,4 @@
-!standard D.03 (00) 03-09-21 AI95-00327/03
+!standard D.03 (00) 03-11-24 AI95-00327/04
!class amendment 03-06-05
!status work item 03-06-05
!status received 03-06-05
@@ -9,19 +9,17 @@
An implementation of dynamic ceiling priorities is proposed. The ceiling
-priority of a protected object (PO) can be dynamically changed by execution
-of a predefined procedure attribute. The execution of this procedure is
-only allowed immediately within a protected procedure or protected entry.
-A similar mechanism, in the form of a read-only attribute, is proposed to read
-the current ceiling of a PO. The execution of this attribute is only allowed
-immediately within any protected operation of the PO.
+priority of a protected object (PO) would be dynamically changed by giving
+access to a new attribute of a protected object.
The ceiling must be changed whilst mutual exclusion for the PO is in force,
according to the ceiling locking protocol. This is the only way to ensure a
consistent ceiling change without the need for a further lock to protect the
ceiling change. Examples are provided to show how to use this feature.
+A prototype implementation by Javier Miranda, Edmond Schonberg and Jorge Real
+concludes that the overheads of this feature is small and not distributed.
In Ada, the ceiling priority of a PO is static and thus it can only be set
@@ -40,69 +38,95 @@
modes. Clearly this approach is error-prone, particularly during composition
of sub-systems, and may have a considerable impact on blocking times. The use of
ceiling of ceilings implies that a task running in a particular mode can be
-blocked by another one unnecessarily, due to an inflated ceiling priority resulting
-from the requirements of a different mode of operation. Consequently, the ceiling
-of ceilings reduces the schedulability of the task set.
+blocked by another one unnecessarily, due to an inflated ceiling priority
+resulting from the requirements of a different mode of operation. Consequently,
+the ceiling of ceilings reduces the schedulability of the task set.
+Add a new section:
-Two new attributes of a protected type or protected object P are defined. In the
-case of a protected type, the attributes apply to the current instance of the
+D.5.1 Dynamic Priorities for Protected Objects
+This clause specifies how the priority of a protected object can be
+modified or queried at run time.
+The following attribute of a protected object is defined:
-Yields the ceiling priority of the protected object P, or the current instance of
-the protected type P. The returned value is of type System.Any_Priority.
-The attribute may only be used immediately within a protected operation of P,
-excluding within any entry barrier expression.
-This attribute is a procedure. It may only be called immediately within the body of a
-protected procedure or entry. The type of the parameter X is System.Any_Priority.
-The effect of the call to P'Set_Priority is to amend the ceiling priority of the
-enclosing protected object (or current instance of the enclosing protected type)
-to X, at completion of the protected action in which it is executed.
-If a task is blocked on a protected entry call, and the call is queued,
-it is a bounded error to lower the ceiling priority of the corresponding
-protected object below the active priority of the blocked task. In this case
-Program_Error is raised in the queued caller, or its priority is temporarily
-lowered, or both, or neither (this is similar wording to that in D.5(11) for
-According to these rules, a read of P'Priority after a call to
-P'Set_Priority within the same protected action will return the old ceiling
-priority. In addition, queued tasks that are serviced as part of the same
-protected action as the one that changes the priority, will execute with the
-old ceiling priority.
-The new attributes are only permitted if Ceiling_Locking locking
-policy is in effect for the active partition.
-A new identifier for pragma Restrictions, No_Dynamic_Ceilings, is introduced to
-provide user control over the legality of these attributes, i.e. the use of
-these attributes is not allowed if No_Dynamic_Ceilings applies to the active
-partition. This restriction is to be added to the definition of pragma
-A new metric needs to be defined to document the cost of a call to P'Set_Priority,
-ie, the difference in time between calls to:
-procedure Set_My_Ceiling (Pr : System.Any_Priority) is
-procedure Set_My_Ceiling (Pr : System.Any_Priority) is
+Yields a variable component of the enclosing protected
+object P (or current instance of the enclosing protected type P) of
+type System.Any_Priority, which denotes the priority of P. Use of
+this attribute is allowed only inside a protected body of P.
+The attribute is part of the current instance of the protected object;
+it is thus defined to be a constant within the body of a protected function,
+but a variable within the body of a protected procedure and an entry_body.
+When the locking policy in effect defines priorities for protected
+objects, 'Priority denotes the priority of the designated protected
+object. Otherwise, the meaning of 'Priority is implementation defined.
+If Locking_Policy Ceiling_Locking is specified then the ceiling priority
+of a protected object P is set to the value of P'Priority at the end
+of each protected action of P.
+If Locking_Policy Ceiling_Locking is specified then it is a bounded error to
+lower the priority of a protected object below the active priority of any task
+that is queued on an entry of the protected object. In this case one of the
+ - Program_Error exception is raised in the queued task;
+ - the entry body is executed, when the entry is open, at the ceiling
+ priority of the protected object;
+ - the entry body is executed, when the entry is open, at the ceiling
+ priority of the protected object and Program_Error exception is raised in
+ the queued task;
+ - the entry body is executed, when the entry is open, at the
+ ceiling priority of the protected object that was in effect when the
+ entry call was queued.
+The implementation shall document the following metric:
+ The difference in execution time of calls to the following procedures
+ in protected object P,
+ protected P is
+ procedure Do_Not_Set_Ceiling (Pr : System.Any_Priority) is
+ procedure Set_Ceiling (Pr : System.Any_Priority) is
+ P'Priority := Pr;
+ end P;
-as protected procedures in a protected object PO with no entries.
+The value of P'Priority following an assignment to the attribute immediately
+reflects the new value even though its impact on the ceiling priority of P is
+postponed until completion of the protected action in which it is executed.
+Change the definition of Restriction identifier No_Dynamic_Priorities:
+ There are no semantic dependences on the package Dynamic_Priorities, and
+ occurrences of attribute 'Priority are not allowed.
+Change D.5(11) to reflect the words used above.
@@ -120,19 +144,19 @@
procedure Set_My_Ceiling(Pr : in System.Any_Priority) is
-- Code before setting the ceiling
- -- Code after setting the ceiling.
+ My_Protected'Priority := Pr;
+ -- Code after setting the ceiling
-- The new ceiling does not take effect
- -- until the end of the protected action
+ -- until the end of this procedure, but the
+ -- new value is return by any read of 'Priority
-- Rest of bodies
- PO: My_Protected; -- Declaration of the PO
+ PO: My_Protected;
In this example, the caller to Set_My_Ceiling must know the name of
the PO whose ceiling is to be changed - the call would have the form
PO.Set_My_Ceiling(Pr). A more flexible scheme can easily be obtained by
@@ -147,6 +171,8 @@
+The use of a protected interface could also achieve this functionality.
Both the old and new values of the ceiling must be retained by the
@@ -154,18 +180,12 @@
against the old value until the new
value takes effect, at the end of the protected action.
-The interface to these features, e.g. the use of P'Priority and P'Set_Priority
-appears to be the easiest way of achieving the required functionality. Allowing
-assignment to an implicit component called P'Priority (e.g. P'Priority := Pr;)
-would be an anomalous use of Ada attributes. One other possibility would be to
-define a pre-defined procedure called Set_Priority, as in the case of dynamic
-task priorities, but this would need PO IDs.
+The interface to these features, e.g. the use of P'Priority
+appears to be the easiest way of achieving the required functionality.
The need for dynamic ceilings and a detailed examination of the many
different ways it could be achieved has been the subject of much
-discussion at four IRTAWs. The following is a summary. At the end of
-this section, the reasons for not allowing 'Priority in entry barriers
+discussion at four IRTAWs. The following is a summary.
Two primary approaches have been considered to make this proposal:
@@ -184,7 +204,7 @@
Three cases can be identified with respect to the relative priorities of tasks
-executing a protected operation, the task calling 'Set_Priority -referred to as
+executing a protected operation, the task assigning to 'Priority -referred to as
the "caller"- and the current and new ceiling priorities:
Case 1: The caller has a lower or equal priority to the current ceiling
@@ -252,8 +272,8 @@
"immediately" inherits the new ceiling. In such case, no other task accessing
the protected object can preempt it, therefore the protected action will be
normally completed even in the presence of a ceiling change. A possible
-implementation of Set_Priority conforming to such semantics would be the
+implementation of an assignment to 'Priority conforming to such semantics
+would be the following:
1. Change variable "ceiling" to New_Ceiling
2. if PO_In_Use and Prio(User_Task) < New_Ceiling then
@@ -267,27 +287,25 @@
-- IMPLEMENTATION AS A PROTECTED OPERATION --
-The second approach -the one that is advocated in this document- proposes to
+The second approach (the one that is advocated in this AI) proposes to
implement the ceiling change as a protected operation, there by avoiding
the problems described above.
-For a given protected object PO, we shall assume the existence of a predefined procedure
-Set_Priority, implemented as an attribute PO'Set_Priority, with an "in" parameter
-of the type System.Any_Priority that expresses the new ceiling priority for PO.
-This attribute can only be used immediately within the body of a protected procedure
-or entry of the affected PO, thus its use is subject to the ceiling locking policy.
-This means that a task calling it must have a priority lower than or equal to the
-protected object's ceiling. Note that we suggest that both attributes can be used
-only immediately within the protected bodies for consistency with other attributes
-such as E'Caller.
+For a given protected object PO, we shall assume the existence of a predefined
+procedure Set_Ceiling, implemented as an assignment to 'Priority, with an "in"
+parameter of the type System.Any_Priority that expresses the new ceiling
+priority for PO. This attribute can only be used immediately within the body of
+a protected procedure or entry of the affected PO, thus its use is subject to
+the ceiling locking policy. This means that a task calling it must have a
+priority lower than or equal to the protected object's ceiling.
-Accordingly, a task calling Set_Priority will be executed in mutual exclusion
+Accordingly, a task calling Set_Ceiling will be executed in mutual exclusion
with other potential users of the protected object, therefore ensuring that no other
task is executing a protected action when the ceiling is changed. This approach
avoids the situation described previously, where data consistency was at risk
due to the asynchronous nature of the ceiling change when it is implemented as
a special operation. It also makes it unnecessary to use a lock on the PO. If
-Set_Priority is implemented as a protected operation, the standard implementation
+Set_Ceiling is implemented as a protected operation, the standard implementation
of ceiling locking is sufficient to guarantee its execution in mutual exclusion
with other users of the protected object.
@@ -308,60 +326,12 @@
Note that we propose that the new ceiling should take effect at the end of the
protected action, instead of at the end of the protected operation that executes
-the Set_Priority call. This is intended to reduce the risk of Program_Error for
+the Set_Ceiling call. This is intended to reduce the risk of Program_Error for
queued tasks that have already successfully performed the initial entry call with
respect to the ceiling check. Those tasks for whom the barrier becomes open as
part of the same protected action as is changing the ceiling will be successfully
executed at the old ceiling priority. Thus the only tasks that will be affected
are those that remain blocked after the entire protected action has been completed.
--- ty IN BARRIERS --
-In principle, the proposal considered the possibility to use the attribute
-'Priority in barrier expressions, to be able to wait until the ceiling
-priority of a PO was equal to a certain value. For instance, in the mode
-change scenario, a new-mode task could wait until the ceiling priority
-of a PO has been adjusted to the new-mode ceiling by providing an entry
-with a barrier to check this. It could be done by means of a PO entry as
-in the following example:
-entry Wait_Proper_Ceiling when PO'Priority = PO_Ceiling(Mode) is
- -- some code
-Looking at this example in detail, it shows a poor programming style that
-may lead to having Program_Error raised very easily: just asking what the
-current ceiling is may be erroneous, since this call must follow Ceiling_Locking.
-With this mechanism, a task with a relatively high priority cannot wait for the
-ceiling to be raised without causing a ceiling violation.
-Note also that the use of 'Priority in a barrier in conjunction with the
-eggshell model and the proxy model (which causes the ceiling change to be
-deferred until the end of the protected action in which 'Set_Priority is
-invoked) causes any tasks that remain on closed barriers, not to be released
-as part of the same protected action. If this was permitted, it could give
-rise to surprising results, in that the task will be released potentially
-much later than expected. The following example illustrates this issue:
- -- initial priority is 12
- entry X (...) when My_PO'Priority = 10 ...
- procedure P (...) is
- My_PO'Set_Priority (10); --> this will take effect in the order:
- -- Service_Entries(...); -- Service pending entry calls
- -- Adjust_Ceiling(...); -- Perform the actual ceiling change
- end P;
-hence the task queued on X will NOT be released just after the execution of P,
-but at the next occasion the barrier will be evaluated.
-Therefore we propose that the use of 'Priority in a barrier expression should
-be rejected and the user should use a more precise form of expression to
-control the release of such a task.
Paper  contains further discussions on the motivation behind the proposal
and other examples (for an earlier version of the feature). Dynamic ceilings
Questions? Ask the ACAA Technical Agent