CVS difference for ais/ai-00327.txt

Differences between 1.10 and version 1.11
Log of other versions for file ais/ai-00327.txt

--- ais/ai-00327.txt	2004/07/27 23:00:59	1.10
+++ ais/ai-00327.txt	2004/11/14 06:37:13	1.11
@@ -1,4 +1,4 @@
-!standard D.03 (13)                                    04-06-24  AI95-00327/06
+!standard D.03 (13)                                    04-11-10  AI95-00327/07
 !standard D.05 (00)
 !standard D.05.01 (00)
 !standard D.05.02 (00)
@@ -14,33 +14,26 @@
 
 !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.
-
-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.
+A mechanism is defined for dynamic ceiling priorities. This enables the
+ceiling priority of a protected object to be changed by assignment to the
+new attribute Priority within a protected operation of the object.
 
 !problem
 
-In Ada, the ceiling priority of a PO is constant and thus it can only be set
-once, by means of pragma Priority, at PO creation time. In contrast, task
-priorities may be set dynamically. The ability to dynamically change protected
-object ceiling priorities is especially required in situations where dynamic
-task priority change occurs, or where a library containing POs with inadequate
-ceilings is used by an application-specific set of tasks and interrupt handlers.
-Examples of dynamic task priority changes include:
+In Ada, the ceiling priority of a protected object is constant and thus it can
+only be set once, by means of pragma Priority, when the object is created. In
+contrast, task priorities may be set dynamically. The ability to dynamically
+change protected object ceiling priorities is especially required in situations
+where dynamic task priority change occurs, or where a library containing
+protected objects with inadequate ceilings is used by an application-specific
+set of tasks and interrupt handlers. Examples of dynamic task priority changes
+include:
 
  - multi-moded systems
  - systems scheduled using dynamic priorities
 
 For multi-moded systems, a common workaround is to use the so-called "ceiling
-of ceilings", i.e. the highest ceiling that the PO can have across all operating
+of ceilings", i.e. the highest ceiling that the protected object can have across all operating
 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
@@ -50,8 +43,19 @@
 
 !proposal
 
-(See wording.)
+An implementation of dynamic ceiling priorities is proposed. The ceiling
+priority of a protected object 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 protected object 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.
+
 !wording
 
 Add a new paragraph after D.3(13)
@@ -80,7 +84,7 @@
 
 Insert after the title of D.5:
 
-This clause describes how the priority of an entity can be queried or modified
+This clause describes how the priority of an entity can be modified or queried
 at run time.
 
 D.5.1 Dynamic Priorities for Tasks
@@ -102,17 +106,17 @@
 The following attribute of a protected object is defined:
 
 P'Priority
-Denotes a non-aliased component of the enclosing protected object P.
-This component is of type System.Any_Priority and its value is the
-priority of P. Reference to this attribute shall appear only inside
-the body of P.
+  Denotes a non-aliased component of the enclosing protected object P.
+  This component is of type System.Any_Priority and its value is the
+  priority of P. Reference to this attribute shall appear only inside
+  the body of P.
 
 The initial value of this attribute is set by pragmas Priority or
 Interrupt_Priority, and can be changed by an assignment.
 
 Dynamic Semantics
 
-If the Locking_Policy Ceiling_Locking is in effect then the ceiling priority
+If the locking policy Ceiling_Locking is in effect 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.
 
@@ -141,9 +145,10 @@
   end P;
 
 Notes
-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.
+Since P'Priority is a normal variable, the value 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.
 
 --
 
@@ -151,7 +156,7 @@
 
 No_Dynamic_Priorities
   There are no semantic dependences on the package Dynamic_Priorities, and
-  no occurrences of attribute 'Priority.
+  no occurrences of the attribute Priority.
 
 !example
 
@@ -172,7 +177,7 @@
       -- Code after setting the priority
       -- The new ceiling does not take effect
       -- until the end of this procedure, but the
-      -- new value is returned by any read of 'Priority
+      -- new value is returned by any read of attribute Priority
     end Set_My_Ceiling;
 
     -- Rest of bodies
@@ -181,8 +186,8 @@
 
   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
+In this example, the caller to Set_My_Ceiling must know the name of the
+protected object 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
 means of an access-to-protected-subprogram, that could be used in the
 implementation of a general ceiling changer:
@@ -213,23 +218,24 @@
 
 Two primary approaches have been considered to make this proposal:
 
-  a) To implement the ceiling change as a special operation on the PO, not
-     necessarily as a protected operation under the ceiling locking protocol.
+  a) To implement the ceiling change as a special operation on the protected
+     object, not necessarily as a protected operation under the ceiling
+     locking protocol.
   b) To implement the ceiling change as a protected operation.
 
 We will discuss now the main problems with a) and later on, how b) solves them.
 
 -- IMPLEMENTATION AS A SPECIAL OPERATION --
 
-The motivation for a) was to be able to change a PO's ceiling from any
-priority, lower or higher than the ceiling, thus allowing to promptly change
-the ceilings from a high priority mode changer (in the mode change scenario).
-This approach was inspired by the use of ceilings in POSIX mutexes. Let's
-explore it.
+The motivation for a) was to be able to change a protected object's ceiling
+from any priority, lower or higher than the ceiling, thus allowing to promptly
+change the ceilings from a high priority mode changer (in the mode change
+scenario). This approach was inspired by the use of ceilings in POSIX mutexes.
+Let's explore it.
 
 Three cases can be identified with respect to the relative priorities of tasks
-executing a protected operation, the task assigning to 'Priority -referred to as
-the "caller"- and the current and new ceiling priorities:
+executing a protected operation, (the task assigning to the attribute
+priority is referred to as the caller):
 
   Case 1: The caller has a lower or equal priority to the current ceiling
     and is changing the ceiling to a higher priority. In this situation the
@@ -239,12 +245,13 @@
     equal to their base priority.
 
   Case 2: The caller has a lower or equal priority to the current ceiling, as
-    in case 1, but now it is changing the ceiling to a lower priority. Here,
-    it is possible that tasks queued on entries might have active priorities
-    higher than the new ceiling. In this situation, the Ceiling_Locking policy could be
-    violated and it would be necessary to raise an appropriate exception to the
-    queued tasks. Currently in Ada, Program_Error is raised when a task tries to
-    call a protected operation in a protected object with a lower ceiling priority.
+    in case 1, but now it is changing the ceiling to a lower priority. Here, it
+    is possible that tasks queued on entries might have active priorities
+    higher than the new ceiling. In this situation, the Ceiling_Locking policy
+    could be violated and it would be necessary to raise an appropriate
+    exception in the queued tasks. Currently in Ada, Program_Error is raised
+    when a task tries to call a protected operation in a protected object with
+    a lower ceiling priority.
 
   Case 3: The caller has a higher priority than the current ceiling. Hence,
     the ceiling change cannot adhere to the ceiling protocol to change the
@@ -288,16 +295,16 @@
 would prevent t8 in the example above to access the PO. The lock eliminates the
 risk for data corruption but the use of locks can cause well-known priority
 inversion problems. More importantly, the implementation of ceiling locking
-on a mono-processor does not require a lock. Hence this solution should also
+on a monoprocessor does not require a lock. Hence this solution should also
 be rejected for efficiency reasons.
 
 A second way to avoid the potential for data corruption is that the task
 executing the protected action when a ceiling change happens to occur,
 "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 an assignment to 'Priority conforming to such semantics
-would be the following:
+completed normally even in the presence of a ceiling change. A possible
+implementation of an assignment to the attribute 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
@@ -312,31 +319,32 @@
 -- IMPLEMENTATION AS A PROTECTED OPERATION --
 
 The second approach (the one that is advocated in this AI) proposes to
-implement the ceiling change as a protected operation, there by avoiding
+implement the ceiling change as a protected operation, thereby avoiding
 the problems described above.
 
 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.
+procedure Set_Ceiling, implemented as an assignment to the attribute Priority,
+with an "in" parameter of the type System.Any_Priority that sets 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 protected object, 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_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_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.
+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 protected object. If 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.
 
 With respect to tasks queued on protected entries, it could be the case that
 the ceiling of the protected object is lowered below the queued task's active
-priority, which represents a bounded error in Ada. According to the Ada
-Reference Manual, paragraph D.5(11):
+priority, which represents a bounded error in Ada. According to D.5(11):
 
     "If a task is blocked on a protected entry call, and the call is queued,
      it is a bounded error to raise its base priority above the ceiling
@@ -406,7 +414,7 @@
 This clause specifies how the base priority of a task can be modified or
 queried at run time.
 @dinss
-This clause describes how the priority of an entity can be queried or modified
+This clause describes how the priority of an entity can be modified or queried
 at run time.
 
 @fa<@s10<@b<D.5.1 Dynamic Priorities for Tasks>>>
@@ -445,7 +453,7 @@
 
 @i<@s8<Dynamic Semantics>>
 
-If the Locking_Policy Ceiling_Locking is in effect then the ceiling priority
+If the locking policy Ceiling_Locking is in effect 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.
 
@@ -475,9 +483,10 @@
    @b<end> P;>
 
 @xindent<@s9<NOTES@hr
-38 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.>>
+38 Since P'Priority is a normal variable, the value 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.>>
 
 !corrigendum D.7(9)
 
@@ -487,7 +496,7 @@
 @dby
 @xhang<@xterm<No_Dynamic_Priorities>
 There are no semantic dependences on the package Dynamic_Priorities, and
-no occurrences of attribute 'Priority.>
+no occurrences of the attribute Priority.>
 
 !ACATS test
 

Questions? Ask the ACAA Technical Agent