Static Semantics
- (1)
- The following language-defined generic library package exists:
(2)
with Ada.Task_Identification; use Ada.Task_Identification;
generic
type Attribute is private;
Initial_Value : in Attribute;
package Ada.Task_Attributes is
(3)
type Attribute_Handle is access all Attribute;
(4)
function Value(T : Task_ID := Current_Task)
return Attribute;
(5)
function Reference(T : Task_ID := Current_Task)
return Attribute_Handle;
(6)
procedure Set_Value(Val : in Attribute;
T : in Task_ID := Current_Task);
procedure Reinitialize(T : in Task_ID := Current_Task);
(7)
end Ada.Task_Attributes;
Dynamic Semantics
- (8)
- When an instance of Task_Attributes is elaborated in a given active
partition, an object of the actual type corresponding to the formal type
Attribute is implicitly created for each task (of that partition) that exists
and is not yet terminated. This object acts as a user-defined attribute of
the task. A task created previously in the partition and not yet terminated
has this attribute from that point on. Each task subsequently created in the
partition will have this attribute when created. In all these cases, the
initial value of the given attribute is Initial_Value.
- (9)
- The Value operation returns the value of the corresponding attribute of
T.
- (10)
- The Reference operation returns an access value that designates the
corresponding attribute of T.
- (11)
- The Set_Value operation performs any finalization on the old value of the
attribute of T and assigns Val to that attribute (see
5.2 and 7.6).
- (12)
- The effect of the Reinitialize operation is the same as Set_Value where
the Val parameter is replaced with Initial_Value.
- (13)
- For all the operations declared in this package, Tasking_Error is raised
if the task identified by T is terminated. Program_Error is raised if the
value of T is Null_Task_ID.
Erroneous Execution
- (14)
- It is erroneous to dereference the access value returned by a given call
on Reference after a subsequent call on Reinitialize for the same task
attribute, or after the associated task terminates.
- (15)
- If a value of Task_ID is passed as a parameter to any of the operations
declared in this package and the corresponding task object no longer exists,
the execution of the program is erroneous.
Implementation Requirements
- (16)
- The implementation shall perform each of the above operations for a
given attribute of a given task atomically with respect to any other of the
above operations for the same attribute of the same task.
- (17)
- When a task terminates, the implementation shall finalize all attributes
of the task, and reclaim any other storage associated with the attributes.
Documentation Requirements
- (18)
- The implementation shall document the limit on the number of attributes
per task, if any, and the limit on the total storage for attribute values per
task, if such a limit exists.
- (19)
- In addition, if these limits can be configured, the implementation shall
document how to configure them.
Metrics
- (20)
- The implementation shall document the following metrics: A task calling
the following subprograms shall execute in a sufficiently high priority as to
not be preempted during the measurement period. This period shall start just
before issuing the call and end just after the call completes. If the
attributes of task T are accessed by the measurement tests, no other task
shall access attributes of that task during the measurement period. For all
measurements described here, the Attribute type shall be a scalar whose size
is equal to the size of the predefined integer size. For each measurement,
two cases shall be documented: one where the accessed attributes are of the
calling task (that is, the default value for the T parameter is used), and
the other, where T identifies another, non-terminated, task.
- (21)
- The following calls (to subprograms in the Task_Attributes package)
shall be measured:
- (22)
- a call to Value, where the return value is Initial_Value;
- (23)
- a call to Value, where the return value is not equal to Initial_Value;
- (24)
- a call to Reference, where the return value designates a value
equal to Initial_Value;
- (25)
- a call to Reference, where the return value designates a value
not equal to Initial_Value;
- (26)
- a call to Set_Value where the Val parameter is not equal to
Initial_Value and the old attribute value is equal to Initial_Value.
- (27)
- a call to Set_Value where the Val parameter is not equal to
Initial_Value and the old attribute value is not equal to
Initial_Value.
Implementation Permissions
- (28)
- An implementation need not actually create the object corresponding to a
task attribute until its value is set to something other than that of
Initial_Value, or until Reference is called for the task attribute.
Similarly, when the value of the attribute is to be reinitialized to that of
Initial_Value, the object may instead be finalized and its storage reclaimed,
to be recreated when needed later. While the object does not exist, the
function Value may simply return Initial_Value, rather than implicitly
creating the object.
- (29)
- An implementation is allowed to place restrictions on the maximum number
of attributes a task may have, the maximum size of each attribute, and the
total storage size allocated for all the attributes of a task.
Implementation Advice
- (30)
- Some implementations are targeted to domains in which memory use at run
time must be completely deterministic. For such implementations, it is
recommended that the storage for task attributes will be pre-allocated
statically and not from the heap. This can be accomplished by either placing
restrictions on the number and the size of the task's attributes, or by using
the pre-allocated storage for the first N attribute objects, and the heap for
the others. In the latter case, N should be documented.
-
- (31)
(12) An attribute always exists (after instantiation), and has the
initial value. It need not occupy memory until the first operation that
potentially changes the attribute value. The same holds true after
Reinitialize.
- (32)
(13) The result of the Reference function should be used with care; it
is always safe to use that result in the task body whose attribute is
being accessed. However, when the result is being used by another task,
the programmer must make sure that the task whose attribute is being
accessed is not yet terminated. Failing to do so could make the program
execution erroneous.
- (33)
(14) As specified in C.7.1, if the parameter T
(in a call on a subprogram of an instance of this package) identifies a
nonexistent task, the execution of the program is erroneous.
-- Email comments, additions, corrections, gripes, kudos, etc. to:
Magnus Kempe -- Magnus.Kempe@di.epfl.ch
Copyright statement
Page last generated: 95-03-12