Rationale for Ada 2005
5.4 The Ravenscar profile
The purpose of the Ravenscar profile is to restrict
the use of many tasking facilities so that the effect of the program
is predictable. The profile was defined by the International Real-Time
Ada Workshops which met twice at the remote village of Ravenscar on the
coast of Yorkshire in North-East England. A general description of the
principles and use of the profile in high integrity systems will be found
in an ISO/IEC Technical Report [2] and so we shall not cover that material
here.
Here is a historical interlude. It is reputed that
the hotel in which the workshops were held was originally built as a
retreat for King George III to keep a mistress. Another odd rumour is
that he ordered all the natural trees to be removed and replaced by metallic
ones whose metal leaves clattered in the wind. It also seems that Henry
Bolingbroke landed at Ravenscar in July 1399 on his way to take the throne
as Henry IV. Ravenscar is mentioned several times by Shakespeare in Act
II of King Richard II; it is spelt Ravenspurg which is slightly confusing
– maybe we need the ability to rename profile identifiers.
A
profile is a mode of operation and is specified by the pragma
Profile
which defines the particular profile to be used. The syntax is
pragma Profile(profile_identifier [ , profile_argument_associations]);
where profile_argument_associations
is simply a list of pragma argument associations separated by commas.
Thus to ensure that
a program conforms to the Ravenscar profile we write
pragma Profile(Ravenscar);
The general idea is that a profile is equivalent
to a set of configuration pragmas.
In the case of Ravenscar the pragma is equivalent
to the joint effect of the following pragmas
pragma Task_Dispatching_Policy(FIFO_Within_Priorities);
pragma Locking_Policy(Ceiling_Locking);
pragma Detect_Blocking;
pragma Restrictions(
No_Abort_Statements,
No_Dynamic_Attachment,
No_Dynamic_Priorities,
No_Implicit_Heap_Allocations,
No_Local_Protected_Objects,
No_Local_Timing_Events,
No_Protected_Type_Allocators,
No_Relative_Delay,
No_Requeue_Statements,
No_Select_Statements,
No_Specific_Termination_Handlers,
No_Task_Allocators,
No_Task_Hierarchy,
No_Task_Termination,
Simple_Barriers,
Max_Entry_Queue_Length => 1,
Max_Protected_Entries => 1,
Max_Task_Entries => 0,
No_Dependence => Ada.Asynchronous_Task_Control,
No_Dependence => Ada.Calendar,
No_Dependence => Ada.Execution_Time.Group_Budget,
No_Dependence => Ada.Execution_Time.Timers,
No_Dependence => Ada.Task_Attributes);
The pragma Detect_Blocking
plus many of the Restrictions identifiers are new to Ada 2005. These
will now be described.
The pragma
Detect_Blocking,
as its name implies, ensures that the implementation will detect a potentially
blocking operation in a protected operation and raise
Program_Error.
Without this pragma the implementation is not required to detect blocking
and so tasks might be locked out for an unbounded time and the program
might even deadlock.
The identifier
No_Dynamic_Attachment
means that there are no calls of the operations in the package
Ada.Interrupts.
The identifier
No_Dynamic_Priorities
means that there is no dependence on the package
Ada.Priorities
as well as no uses of the attribute
Priority
(this is a new attribute for protected objects as explained at the end
of this section).
Note that the rules are that you cannot read as well
as not write the priorities – this applies to both the procedure
for reading task priorities and reading the attribute for protected objects.
The identifier
No_Local_Protected_Objects
means that protected objects can only be declared at library level and
the identifier
No_Protected_Type_Allocators
means that there are no allocators for protected objects or objects containing
components of protected types.
The identifier
No_Local_Timing_Events
means that objects of the type
Timing_Event
in the package
Ada.Real_Time.Timing_Events
can only be declared at library level. This package is described in Section
6 below.
The identifiers
No_Relative_Delay,
No_Requeue_Statements, and
No_Select_Statements
mean that there are no relative delay, requeue or select statements respectively.
The identifier
No_Specific_Termination_Handlers
means that there are no calls of the procedure
Set_Specific_Handler
or the function
Specific_Handler in the package
Task_Termination and the identifier
No_Task_Termination
means that all tasks should run for ever. Note that we are permitted
to set a fallback handler so that if any task does attempt to terminate
then it will be detected.
The identifier
Simple_Barriers
means that the Boolean expression in a barrier of an entry of a protected
object shall be either a static expression (such as
True)
or a Boolean component of the protected object itself.
The Restrictions identifier
Max_Entry_Queue_Length
sets a limit on the number of calls permitted on an entry queue. It is
an important property of the Ravenscar profile that only one call is
permitted at a time on an entry queue of a protected object.
The identifier
No_Dependence
is not specific to the Real-Time Systems annex and is properly described
in Section
6.4. In essence it indicates that
the program does not depend upon the given language defined package.
In this case it means that a program conforming to the Ravenscar profile
cannot use any of the packages
Asynchronous_Task_Control,
Calendar,
Execution_Time.Group_Budget,
Execution_Time.Timers and
Task_Attributes.
Some of these packages are new and are described later in this chapter
(in Section
5.6).
Note that No_Dependence
cannot be used for No_Dynamic_Attachment because
that would prevent use of the child package Ada.Interrupts.Names.
All the other restrictions identifiers used by the
Ravenscar profile were already defined in Ada 95. Note also that the
identifier
No_Asynchronous_Control has been
moved to
Annex
J because it can now be replaced by the use of
No_Dependence.
© 2005, 2006, 2007 John Barnes Informatics.
Sponsored in part by: