D.7 Tasking Restrictions
This subclause defines restrictions that can be used
with a pragma Restrictions (see
13.12) to
facilitate the construction of highly efficient tasking run-time systems.
Static Semantics
A
scalar
expression
within a protected unit is said to be
pure-barrier-eligible if
it is one of the following:
a static expression;
a
name
that statically names (see
4.9) a scalar subcomponent
of the immediately enclosing protected unit;
a call to a predefined relational operator or boolean
logical operator (and, or, xor, not), where
each operand is pure-barrier-eligible;
a short-circuit control form both of whose operands
are pure-barrier-eligible;
a pure-barrier-eligible
expression
enclosed in parentheses.
The following
restriction_identifiers
are language defined:
No task depends on a master other than the library-level master.
Objects of a type that needs finalization (see
7.6)
are declared only at library level. If an access type does not have library-level
accessibility, then there are no
allocators
of the type where the type determined by the
subtype_mark
of the
subtype_indication
or
qualified_expression
needs finalization.
There are no
abort_statements,
and there is no use of a
name
denoting Task_Identification.Abort_Task.
No_Terminate_Alternatives
There are no
allocators
for task types or types containing task subcomponents.
In the case of an initialized
allocator
of an access type whose designated type is class-wide and limited, a
check is made that the specific type of the allocated object has no task
subcomponents. Program_Error is raised if this check fails.
No_Implicit_Heap_Allocations
There are no operations that implicitly require heap storage allocation
to be performed by the implementation. The operations that implicitly
require heap storage allocation are implementation defined.
No_Dynamic_Priorities
There are no semantic dependences on the package Dynamic_Priorities,
and no occurrences of the attribute Priority.
There is no use of a
name
denoting any of the operations defined in package Interrupts (Is_Reserved,
Is_Attached, Current_Handler, Attach_Handler, Exchange_Handler, Detach_Handler,
and Reference).
No_Dynamic_CPU_Assignment
No task has the CPU aspect specified to be a non-static expression. Each
task (including the environment task) that has the CPU aspect specified
as Not_A_Specific_CPU will be assigned to a particular implementation-defined
CPU. The same is true for the environment task when the CPU aspect is
not specified. Any other task without a CPU aspect will activate and
execute on the same processor as its activating task.
No_Local_Protected_Objects
Protected objects are declared only at library level.
Timing_Events are declared only at library level.
No_Protected_Type_Allocators
There are no
allocators
for protected types or types containing protected type subcomponents.
In the case of an initialized
allocator
of an access type whose designated type is class-wide and limited, a
check is made that the specific type of the allocated object has no protected
subcomponents. Program_Error is raised if this check fails.
There are no
delay_relative_statements,
and there is no use of a
name
that denotes the Timing_Events.Set_Handler subprogram that has a Time_Span
parameter.
No_Specific_Termination_Handlers
There is no use of a
name
denoting the Set_Specific_Handler and Specific_Handler subprograms in
Task_Termination.
No_Tasks_Unassigned_To_CPU
The CPU aspect is specified for the environment task. No CPU aspect is
specified to be statically equal to Not_A_Specific_CPU. If aspect CPU
is specified (dynamically) to the value Not_A_Specific_CPU, then Program_Error
is raised. If Set_CPU or Delay_Until_And_Set_CPU are called with the
CPU parameter equal to Not_A_Specific_CPU, then Program_Error is raised.
The Boolean expression in each protected entry barrier is pure-barrier-eligible.
The Boolean expression in each entry barrier is either a static expression
or a
name
that statically names (see
4.9) a subcomponent
of the enclosing protected object.
The following
restriction_parameter_identifiers
are language defined:
Specifies the maximum number of alternatives in a
selective_accept.
Specifies the maximum number of entries per task. The bounds of every
entry family of a task unit shall be static, or shall be defined by a
discriminant of a subtype whose corresponding bound is static. A value
of zero indicates that no rendezvous are possible.
Max_Protected_Entries
Specifies the maximum number of entries per protected type. The bounds
of every entry family of a protected unit shall be static, or shall be
defined by a discriminant of a subtype whose corresponding bound is static.
Dynamic Semantics
The following
restriction_identifier
is language defined:
All tasks are nonterminating. It is implementation-defined what happens
if a task attempts to terminate. If there is a fall-back handler (see
C.7.3) set for the partition it should be called when the first task
attempts to terminate.
The following
restriction_parameter_identifiers
are language defined:
Specifies the maximum portion (in storage elements) of a task's Storage_Size
that can be retained by a blocked task. If an implementation chooses
to detect a violation of this restriction, Storage_Error should be raised;
otherwise,
the behavior is implementation defined.
Max_Asynchronous_Select_Nesting
Specifies the maximum dynamic nesting level of
asynchronous_selects.
A value of zero prevents the use of any
asynchronous_select
and, if a program contains an
asynchronous_select,
it is illegal. If an implementation chooses to detect a violation of
this restriction for values other than zero, Storage_Error should be
raised;
otherwise,
the behavior is implementation defined.
Specifies the maximum number of task creations that may be executed over
the lifetime of a partition, not counting the creation of the environment
task. A value of zero prevents any task creation and, if a program contains
a task creation, it is illegal. If an implementation chooses to detect
a violation of this restriction, Storage_Error should be raised;
otherwise,
the behavior is implementation defined.
Max_Entry_Queue_Length defines the maximum number of calls that are queued
on an entry. Violation of this restriction results in the raising of
Program_Error at the point of the call or requeue.
No_Standard_Allocators_After_Elaboration
Specifies that an
allocator
using a standard storage pool (see
13.11)
shall not occur within a parameterless library subprogram, nor within
the
handled_sequence_of_statements
of a task body. For the purposes of this rule, an
allocator
of a type derived from a formal access type does not use a standard storage
pool.
At run time, Storage_Error is raised if
an
allocator
using a standard storage pool is evaluated after the elaboration of the
library_items
of the partition has completed.
It is implementation defined whether the use of pragma
Restrictions results in a reduction in executable program size, storage
requirements, or execution time. If possible, the implementation should
provide quantitative descriptions of such effects for each restriction.
Implementation Advice
When feasible, the implementation should take advantage
of the specified restrictions to produce a more efficient implementation.
NOTE The above Storage_Checks can
be suppressed with pragma Suppress.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe