D.16.1 Multiprocessor Dispatching Domains
This clause allows implementations on multiprocessor
platforms to be partitioned into distinct dispatching domains during
The following language-defined library package
package System.Multiprocessors.Dispatching_Domains is
Dispatching_Domain_Error : exception;
type Dispatching_Domain (<>) is limited private;
System_Dispatching_Domain : constant Dispatching_Domain;
function Create (First, Last : CPU) return Dispatching_Domain;
function Get_First_CPU (Domain : Dispatching_Domain) return CPU;
function Get_Last_CPU (Domain : Dispatching_Domain) return CPU;
function Get_Dispatching_Domain (T : Task_Id := Current_Task)
procedure Assign_Task (Domain : in out Dispatching_Domain;
CPU : in CPU_Range := Not_A_Specific_CPU;
T : in Task_Id := Current_Task);
procedure Set_CPU (CPU : in CPU_Range; T : in Task_Id := Current_Task);
function Get_CPU (T : Task_Id := Current_Task) return CPU_Range;
procedure Delay_Until_And_Set_CPU (
Delay_Until_Time : in Ada.Real_Time.Time; CPU : in CPU_Range);
... -- not specified by the language
The type Dispatching_Domain represents a series
of processors on which a task may execute. Each processor is contained
within exactly one Dispatching_Domain. System_Dispatching_Domain contains
the processor or processors on which the environment task executes. At
program start-up all processors are contained within System_Dispatching_Domain.
The value of aspect Dispatching_Domain is an expression,
which shall be of type Dispatching_Domains.Dispatching_Domain. This aspect
is the domain to which the task (or all objects of the task type) are
for Dispatching_Domain: Domain
(group of processors) on which a given task should run.
The Dispatching_Domain aspect shall not be specified
for a task interface.
The expression specified for the Dispatching_Domain
aspect of a task is evaluated for each task object (see 9.1).
The Dispatching_Domain value is then associated with the task object
whose task declaration specifies the aspect.
If a task is not explicitly assigned to any domain,
it is assigned to that of the activating task. A task always executes
on some CPU in its domain.
If both Dispatching_Domain and CPU are specified
for a task, and the CPU value is not contained within the range of processors
for the domain (and is not Not_A_Specific_CPU), the activation of the
task is defined to have failed, and it becomes a completed task (see
The function Create creates and returns a Dispatching_Domain
containing all the processors in the range First .. Last. These processors
are removed from System_Dispatching_Domain. A call of Create will raise
Dispatching_Domain_Error if any designated processor is not currently
in System_Dispatching_Domain, or if the system cannot support a distinct
domain over the processors identified, or if a processor has a task assigned
to it, or if the allocation would leave System_Dispatching_Domain empty.
A call of Create will raise Dispatching_Domain_Error if the calling task
is not the environment task, or if Create is called after the call to
the main subprogram.
The function Get_First_CPU returns the first CPU
in Domain; Get_Last_CPU returns the last one.
The function Get_Dispatching_Domain returns the
Dispatching_Domain on which the task is assigned.
A call of the procedure Assign_Task assigns task
T to the CPU within Dispatching_Domain Domain. Task T can now execute
only on CPU unless CPU designates Not_A_Specific_CPU, in which case it
can execute on any processor within Domain. The exception Dispatching_Domain_Error
is propagated if T is already assigned to a Dispatching_Domain other
than System_Dispatching_Domain, or if CPU is not one of the processors
of Domain (and is not Not_A_Specific_CPU). A call of Assign_Task is a
task dispatching point for task T. If T is the Current_Task the effect
is immediate, otherwise the effect is as soon as practical. Assigning
a task to System_Dispatching_Domain that is already assigned to that
domain has no effect.
A call of procedure Set_CPU assigns task T to the
CPU. Task T can now execute only on CPU, unless CPU designates Not_A_Specific_CPU,
in which case it can execute on any processor within its Dispatching_Domain.
The exception Dispatching_Domain_Error is propagated if CPU is not one
of the processors of the Dispatching_Domain on which T is assigned (and
is not Not_A_Specific_CPU). A call of Set_CPU is a task dispatching point
for task T. If T is the Current_Task the effect is immediate, otherwise
the effect is as soon as practical.
The function Get_CPU returns the processor assigned
to task T, or Not_A_Specific_CPU if the task is not assigned to a processor.
A call of Delay_Until_And_Set_CPU delays the calling
task for the designated time and then assigns the task to the specified
processor when the delay expires. The exception Dispatching_Domain_Error
is propagated if P is not one of the processors of the calling task's
Dispatching_Domain (and is not Not_A_Specific_CPU).
The implementation shall perform the operations
Assign_Task, Set_CPU, Get_CPU and Delay_Until_And_Set_CPU atomically
with respect to any of these operations on the same dispatching_domain,
processor or task.
Each dispatching domain should have separate and
disjoint ready queues.
Each dispatching domain should have
separate and disjoint ready queues.
The implementation shall document the processor(s)
on which the clock interrupt is handled and hence where delay queue and
ready queue manipulations occur. For any Interrupt_Id whose handler can
execute on more than one processor the implementation shall also document
this set of processors.
The processor(s) on which the clock
interrupt is handled; the processors on which each Interrupt_Id can be
An implementation may limit the number of dispatching
domains that can be created and raise Dispatching_Domain_Error if an
attempt is made to exceed this number.
Extensions to Ada 2005
The package System.Multiprocessors.Dispatching_Domains
and the aspect Dispatching_Domains are new.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe