D.3 Priority Ceiling Locking
This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue
[This subclause specifies the interactions between priority task scheduling and protected object ceilings. This interaction is based on the concept of the ceiling priority of a protected object.]
Syntax
2The form of a pragma
Locking_Policy is as follows:
pragma Locking_Policy(policy_identifier
);
Legality Rules
4The policy_identifier
shall either be Ceiling_Locking or an implementation-defined identifier
.
Post-Compilation Rules
5A Locking_Policy pragma is a configuration pragma.
Dynamic Semantics
6/2{8652/0073} [A locking policy specifies the details of protected object locking. All protected objects have a priority. The locking policy specifies the meaning of the priority of a protected object, and the relationships between these priorities and task priorities. In addition, the policy specifies the state of a task when it executes a protected action, and how its active priority is affected by the locking.] The locking policy is specified by a Locking_Policy pragma. For implementation-defined locking policies, the meaning of the priority of a protected object is implementation defined. If no Locking_Policy pragma applies to any of the program units comprising a partition, the locking policy for that partition, as well as the meaning of the priority of a protected object, are implementation defined.
The expression
specified for the Priority or Interrupt_Priority aspect (see D.1) is evaluated as part of the creation of the corresponding protected object and converted to the subtype System.Any_Priority or System.Interrupt_Priority, respectively. The value of the expression is the initial priority of the corresponding protected object. If no Priority or Interrupt_Priority aspect is specified for a protected object, the initial priority is specified by the locking policy.
There is one predefined locking policy, Ceiling_Locking; this policy is defined as follows:
- Every protected object has a ceiling priority, which is determined by either a Priority or Interrupt_Priority aspect as defined in D.1, or by assignment to the Priority attribute as described in D.5.2. The ceiling priority of a protected object (or ceiling, for short) is an upper bound on the active priority a task can have when it calls protected operations of that protected object.
- The initial ceiling priority of a protected object is equal to the initial priority for that object.
- If an Interrupt_Handler or Attach_Handler aspect (see C.3.1) is specified for a protected subprogram of a protected type that does not have either the Priority or Interrupt_Priority aspect specified, the initial priority of protected objects of that type is implementation defined, but in the range of the subtype System.Interrupt_Priority.
- If neither aspect Priority nor Interrupt_Priority is specified for a protected type, and no protected subprogram of the type has aspect Interrupt_Handler or Attach_Handler specified, then the initial priority of the corresponding protected object is System.Priority'Last.
- While a task executes a protected action, it inherits the ceiling priority of the corresponding protected object.
- When a task calls a protected operation, a check is made that its active priority is not higher than the ceiling of the corresponding protected object; Program_Error is raised if this check fails.
If the task dispatching policy specified for the ceiling priority of a protected object is EDF_Within_Priorities, the following additional rules apply:
- Every protected object has a relative deadline, which is determined by a Relative_Deadline aspect as defined in D.2.6, or by assignment to the Relative_Deadline attribute as described in D.5.2. The relative deadline of a protected object represents a lower bound on the relative deadline a task may have when it calls a protected operation of that protected object.
- If aspect Relative_Deadline is not specified for a protected type then the initial relative deadline of the corresponding protected object is Ada.Real_Time.Time_Span_Zero.
- While a task executes a protected action on a protected object P, it inherits the relative deadline of P. In this case, let DF be 'now' ('now' is obtained via a call on Ada.Real_Time.Clock at the start of the action) plus the deadline floor of P. If the active deadline of the task is later than DF, its active deadline is reduced to DF[; the active deadline is unchanged otherwise].
- When a task calls a protected operation, a check is made that its active deadline minus its last release time is not less than the relative deadline of the corresponding protected object; Program_Error is raised if this check fails.
Bounded (Run-Time) Errors
13.6/5Following any change of priority, it is a bounded error for the active priority of any task with a call queued on an entry of a protected object to be higher than the ceiling priority of the protected object. In this case one of the following applies:
- at any time prior to executing the entry body, Program_Error is raised in the calling task;
- when the entry is open, the entry body is executed at the ceiling priority of the protected object;
- when the entry is open, the entry body is executed at the ceiling priority of the protected object and then Program_Error is raised in the calling task; or
- when the entry is open, the entry body is executed at the ceiling priority of the protected object that was in effect when the entry call was queued.
abortable_part
, so long as its priority is lowered before it gets to the end and needs to cancel the call. The priority might need to be lowered to allow it to remove the call from the entry queue, in order to avoid violating the ceiling. This seems relatively harmless, since there is an error, and the task is about to start raising an exception anyway. Implementation Permissions
14The implementation is allowed to round all ceilings in a certain subrange of System.Priority or System.Interrupt_Priority up to the top of that subrange, uniformly.
Implementations are allowed to define other locking policies, but are not required to support specifying more than one locking policy per partition.
[Since implementations are allowed to place restrictions on code that runs at an interrupt-level active priority (see C.3.1 and D.2.1), the implementation may implement a language feature in terms of a protected object with an implementation-defined ceiling, but the ceiling shall be no less than Priority'Last.]
allocator
s to fail when evaluated at interrupt priority. Note that the ceiling of such an object has to be at least Priority'Last, since there is no permission for allocator
s to fail when evaluated at a noninterrupt priority. Implementation Advice
17The implementation should use names that end with “_Locking” for implementation-defined locking policies.
Extensions to Ada 95
Wording Changes from Ada 95
Wording Changes from Ada 2005
pragma
s Priority and Interrupt_Priority are now obsolescent.