Contents Index Previous Next
D.3 Priority Ceiling Locking
1
[This clause 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
2
The form of
a pragma Locking_Policy is as follows:
3
pragma Locking_Policy(
policy_identifier);
Legality Rules
4
The
policy_identifier
shall either be Ceiling_Locking or an implementation-defined
identifier.
4.a
Implementation defined: Implementation-defined
policy_identifiers
allowed in a pragma Locking_Policy.
Post-Compilation Rules
5
{configuration pragma (Locking_Policy)
[partial]} {pragma, configuration
(Locking_Policy) [partial]} A Locking_Policy
pragma is a configuration pragma.
Dynamic Semantics
6/1
{
8652/0073}
{locking policy} [A locking
policy specifies the details of protected object locking. These rules specify
whether or not protected objects have priorities, 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 effect of a Priority
or Interrupt_Priority pragma on a protected object is implementation defined.
If no Locking_Policy pragma
applies toappears in any of the program
units comprising a partition, the locking policy for that partition, as well
as the effect of specifying either a Priority or Interrupt_Priority pragma for
a protected object, are implementation defined.
7
There is one predefined
locking policy, Ceiling_Locking; this policy is defined as follows:
8
- {ceiling priority (of a protected object)}
Every protected object has a ceiling priority,
which is determined by either a Priority or Interrupt_Priority pragma as defined
in D.1. 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.
9
- The expression of
a Priority or Interrupt_Priority pragma 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 ceiling priority of the corresponding protected object. {implicit
subtype conversion (pragma Priority) [partial]} {implicit
subtype conversion (pragma Interrupt_Priority) [partial]}
10
- If an Interrupt_Handler or Attach_Handler pragma (see C.3.1)
appears in a protected_definition without
an Interrupt_Priority pragma, the ceiling priority of protected objects of
that type is implementation defined, but in the range of the subtype System.Interrupt_Priority.
10.a
Implementation defined: Default
ceiling priorities.
11
- If no pragma Priority,
Interrupt_Priority, Interrupt_Handler, or Attach_Handler is specified
in the protected_definition, then
the ceiling priority of the corresponding protected object is System.Priority'Last.
12
- While a task executes a protected action, it inherits the
ceiling priority of the corresponding protected object.
13
- {Ceiling_Check [partial]} {check,
language-defined (Ceiling_Check)} {Program_Error
(raised by failure of run-time check)} 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.
Implementation Permissions
14
The 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.
14.a
Discussion: For example,
an implementation might use Priority'Last for all ceilings in Priority,
and Interrupt_Priority'Last for all ceilings in Interrupt_Priority. This
would be equivalent to having two ceiling priorities for protected objects,
``nonpreemptible'' and ``noninterruptible'', and is an allowed behavior.
14.b
Note that the implementation cannot
choose a subrange that crosses the boundary between normal and interrupt
priorities.
15
Implementations are allowed to define other locking
policies, but need not support more than one such policy per partition.
16
[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.]
16.a
Implementation defined: The
ceiling of any protected object used internally by the implementation.
16.b
Proof: This permission
follows from the fact that the implementation can place restrictions
on interrupt handlers and on any other code that runs at an interrupt-level
active priority.
16.c
The implementation might protect
a storage pool with a protected object whose ceiling is Priority'Last,
which would cause allocators 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 allocators to fail when evaluated
at a non-interrupt priority.
Implementation Advice
17
The implementation should use names that end
with ``_Locking'' for implementation-defined locking policies.
18
16 While a task executes
in a protected action, it can be preempted only by tasks whose active
priorities are higher than the ceiling priority of the protected object.
19
17 If a protected object
has a ceiling priority in the range of Interrupt_Priority, certain interrupts
are blocked while protected actions of that object execute. In the extreme,
if the ceiling is Interrupt_Priority'Last, all blockable interrupts are
blocked during that time.
20
18 The ceiling priority of a protected
object has to be in the Interrupt_Priority range if one of its procedures is
to be used as an interrupt handler (see C.3).
21
19 When specifying the ceiling
of a protected object, one should choose a value that is at least as
high as the highest active priority at which tasks can be executing when
they call protected operations of that object. In determining this value
the following factors, which can affect active priority, should be considered:
the effect of Set_Priority, nested protected operations, entry calls,
task activation, and other implementation-defined factors.
22
20 Attaching a protected procedure
whose ceiling is below the interrupt hardware priority to an interrupt causes
the execution of the program to be erroneous (see C.3.1).
23
21 On a single processor
implementation, the ceiling priority rules guarantee that there is no
possibility of deadlock involving only protected subprograms (excluding
the case where a protected operation calls another protected operation
on the same protected object).
Contents Index Previous Next Legal