Ada Reference Manual (Ada 2022) — Legal Information

# D.7 Tasking Restrictions

1/3
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

1.1/5
A scalar expression within a protected unit is said to be pure-barrier-eligible if it is one of the following:
1.2/5
a static expression;
1.3/5
a name that statically names (see 4.9) a scalar subcomponent of the immediately enclosing protected unit;
1.4/5
a Count attribute_reference whose prefix statically denotes an entry declaration of the immediately enclosing unit;
1.5/5
a call to a predefined relational operator or boolean logical operator (and, or, xor, not), where each operand is pure-barrier-eligible;
1.6/5
a membership test whose tested_simple_expression is pure-barrier-eligible, and whose membership_choice_list meets the requirements for a static membership test (see 4.9);
1.7/5
a short-circuit control form both of whose operands are pure-barrier-eligible;
1.8/5
a conditional_expression all of whose conditions, selecting_expressions, and dependent_expressions are pure-barrier-eligible; or
1.9/5
a pure-barrier-eligible expression enclosed in parentheses.
2
The following restriction_identifiers are language defined:
3/3
No_Task_Hierarchy
No task depends on a master other than the library-level master.
4/3
No_Nested_Finalization
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.
5/3
No_Abort_Statements
There are no abort_statements, and there is no use of a name denoting Task_Identification.Abort_Task.
6
No_Terminate_Alternatives
There are no selective_accepts with terminate_alternatives.
7
No_Task_Allocators
There are no allocators for task types or types containing task subcomponents.
7.1/3
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.
8
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.
9/2
No_Dynamic_Priorities
There are no semantic dependences on the package Dynamic_Priorities, and no occurrences of the attribute Priority.
10/3
No_Dynamic_Attachment
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).
10.1/4
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.
10.2/3
No_Local_Protected_Objects
Protected objects are declared only at library level.
10.3/3
No_Local_Timing_Events
Timing_Events are declared only at library level.
10.4/2
No_Protected_Type_Allocators
There are no allocators for protected types or types containing protected type subcomponents.
10.5/3
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.
10.6/3
No_Relative_Delay
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.
10.7/3
No_Requeue_Statements
There are no requeue_statements.
10.8/3
No_Select_Statements
There are no select_statements.
10.9/3
No_Specific_Termination_Handlers
There is no use of a name denoting the Set_Specific_Handler and Specific_Handler subprograms in Task_Termination.
10.10/4
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.
10.11/5
Pure_Barriers
The Boolean expression in each protected entry barrier is pure-barrier-eligible.
10.12/5
Simple_Barriers
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.
11
The following restriction_parameter_identifiers are language defined:
12
Max_Select_Alternatives
Specifies the maximum number of alternatives in a selective_accept.
13
Max_Task_Entries
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.
14
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

15/2
The following restriction_identifier is language defined:
15.1/2
No_Task_Termination
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.
16
The following restriction_parameter_identifiers are language defined:
17/1
Max_Storage_At_Blocking
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.
18/1
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.
19/1
Max_Tasks
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.
19.1/2
Max_Entry_Queue_Length
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.
19.2/3
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.
19.3/3
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.
20
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

21
When feasible, the implementation should take advantage of the specified restrictions to produce a more efficient implementation.
22
NOTE The above Storage_Checks can be suppressed with pragma Suppress.

Ada 2005 and 2012 Editions sponsored in part by Ada-Europe