D.16 Multiprocessor Implementation
This subclause allows implementations on multiprocessor platforms to
The following language-defined library package exists:
Preelaborate, Nonblocking, Global => in out synchronized is(Multiprocessors);
CPU_Range is range
0 .. implementation-defined
Not_A_Specific_CPU : constant
CPU_Range := 0;
1 .. CPU_Range'Last;
Implementation defined: The value of
CPU_Range'Last in System.Multiprocessors.
A call of Number_Of_CPUs returns the number of processors available to
the program. Within a given partition, each call on Number_Of_CPUs will
return the same value.
The aspect CPU is an expression
which shall be of type System.Multiprocessors.CPU_Range.
Aspect Description for CPU: Processor
on which a given task, or calling task for a protected
operation, should run.
specified for the CPU aspect of a task or protected type
is evaluated for
each time an task
object of the corresponding task type is created
(see 9.1 and 9.4
). The CPU value is then associated
with the task
object whose task declaration specifies the aspect
The CPU aspect has no effect if it is specified for a subprogram other
than the main subprogram; the CPU value is not associated with any task.
The CPU value is associated with the environment task if the CPU aspect
is specified for the main subprogram. If the CPU aspect is not specified
for the main subprogram it is implementation defined on which processor
the environment task executes.
Implementation defined: The processor
on which the environment task executes in the absence of a value for
the aspect CPU.
For a task, the The
CPU value determines the processor on which the task will activate and
execute; the task is said to be assigned to that processor. If the CPU
value is Not_A_Specific_CPU, then the task is not assigned to a processor.
A task without a CPU aspect specified will activate and execute on the
same processor as its activating task if the activating task is assigned
a processor. If the CPU value is not in the range of System.Multiprocessors.CPU_Range
or is greater than Number_Of_CPUs the task is defined to have failed,
and it becomes a completed task (see 9.2
For a protected type, the CPU value determines
the processor on which calling tasks will execute; the protected object
is said to be assigned to that processor. If the CPU value is Not_A_Specific_CPU,
then the protected object is not assigned to a processor. A call to a
protected object that is assigned to a processor from a task that is
not assigned a processor or is assigned a different processor raises
When a protected object is assigned to a CPU, only
tasks also assigned to that CPU can call it. In contrast, a protected
object that is not assigned to a specific CPU can be called by any task
on any processor (subject, of course, to visibility and ceiling priority
restrictions). As noted below, when the tasks and protected object are
necessarily on the same CPU, a simpler implementation can be used.
Starting a protected action on a protected object
statically assigned to a processor should be implemented without busy-waiting.
is a form of lock and can be a source of deadlock. Busy-waiting is typically
needed for starting protected actions on multiprocessors, but if all
tasks calling a protected object execute on the same CPU, this locking
isn't needed and the source of deadlock and associated overhead can be
Starting a protected action on a protected
object statically assigned to a processor should not use busy-waiting.
Extensions to Ada 2005
Extensions to Ada 2012
Aspect CPU can now be applied
to protected types, in order to avoid the overhead and deadlock potential
of multiprocessor execution.
Wording Changes from Ada 2012
Corrigendum: Clarified when the CPU aspect
expression is evaluated.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe