Version 1.5 of ais/ai-00206.txt

Unformatted version of ais/ai-00206.txt version 1.5
Other versions for file ais/ai-00206.txt

!standard C.7.1 (10)          99-07-27 AI95-00206/02
!class ramification 98-09-29
!status WG9 approved 99-06-12
!status ARG Approved (7-0-0) 98-10-08
!status work item 98-09-29
!status received 98-09-29
!priority Medium
!difficulty Easy
!subject Ada.Task_Identification.Is_Callable for the environment task
!summary
Ada.Task_Identification.Is_Callable called with a Task_Id value designating the environment task returns True while the main subprogram is executing and False once the main subprogram has returned and the environment task starts waiting for library-level tasks to terminate.
!question
What is the behavior of Ada.Task_Identification.Is_Callable for the environment task? In particular, does it change in value from True to False when the main subprogram exits and starts waiting for library-level tasks to terminate? (Yes)
!response
The note C.7.1(21) says that Ada.Task_Identification.Current_Task can return a Task_Id value designating the environment task. The definition of Is_Callable (in 9.8(2)) is that it is True unless the task is completed or abnormal. The structure of the environment task given in 10.2(10-12), and the dynamic semantics of 10.2(25) tell us that the environment task is completed before waiting for dependent tasks. The erroneous execution case of C.7.1(18) should not apply, as the environment task continues to exist until the partition terminates.
Therefore, the value of Ada.Task_Identification.Is_Callable is well defined. It is possible to test the value after the completion of the environment task in a library-level task (while the environment task is waiting for dependent tasks to terminate). Thus it cannot be implemented purely as a return of True at all times.
The Ada.Task_Identification.Is_Callable flag can be useful, as a library-level task can use the value to terminate itself once the partition has completed. This is especially important to bullet-proof a reusable package containing a library task. At least one commercial Ada library uses this technique.
!ACATS test
A C-Test should be created to test this case.
!appendix

!topic Is_Callable and the environment task.
!reference RM95-C.7.1(10);6.0
!reference RM95-C.7.1(21);6.0
!reference RM95-9.9(2);6.0
!reference RM95-9.3(5);6.0
!reference RM95-10.2(8);6.0
!reference RM95-10.2(25);6.0
!from Randy Brukardt 98-08-07
<<reference as: 1998-15876.a Randy Brukardt  1998-8-7>>
!discussion

What is the behavior of Ada.Task_Identification.Is_Callable for the environment
task? In particular, does it change in value from True to False when the main
subprogram exits and starts waiting for library-level tasks to terminate?

The note C.7.1(21) makes it clear that it is intended that the package
Ada.Task_Identification be able to return and therefore process a Task_Id
identifying the environment task. It is easy to get such a Task_Id, just add an
object to the elaboration of a library-level package: Environment_Task_Id :
Ada.Task_Identification.Task_Id := Ada.Task_Identification.Current_Task;

The definition of Is_Callable (C.7.1(10)) refers to the definition of the
Callable attribute (9.9(2) "A task is callable unless it is completed or
abnormal."). A task is completed when its body is completed.

10.2(8) describes the environment task as elaborating packages and then calling
the main subprogram. 10.2(25) describes the execution of a partition. It
includes the following statement "When the environment task completes (normally
or abnormally), it waits for the termination of all such [library-level] tasks,
then finalizes any remaining objects of the partition."

When the environment task completes, the other rules would seem to imply that
Is_Callable for the environment task would become False. However, some of the
best minds in Ada seem to think otherwise; therefore I'm submitting the question
to the ARG.

The value of Is_Callable would be useful to determine whether the main
subprogram has completed. A package with embedded tasks could use this
information to determine when to terminate, without requiring any
cooperation from the main program.  This is of benefit to "canned"
packages, which ought to be designed to work even in the face of common
user errors. For instance, needing a "Shutdown" routine makes a package
more fragile, because it is easy for the user of the package to forget to
call the routine (or an exception propagates past the call, causing it not
to be called).

If a "canned" package includes a task, it is important that the task be
able to terminate itself appropriately. Unfortunately, finalization cannot
be used for this purpose, since library-level tasks must terminate before
any library-level objects are finalized. Therefore, another technique must
be used. If the task cannot sit on a terminate alternative (perhaps because
it must poll a resource), a function which returns the status of the
environment task is another solution - and Ada 95 already has the function.

This problem has arisen in Claw in the task which handles Window messages,
it is not academic.


						Randy.
*********************************

!topic Is_Callable and the environment task.
!reference RM95-C.7.1(10);6.0
!reference RM95-C.7.1(21);6.0
!reference RM95-9.9(2);6.0
!reference RM95-9.3(5);6.0
!reference RM95-10.2(8);6.0
!reference RM95-10.2(25);6.0
!reference 1998-15876.a Randy Brukardt 98-08-07
!from Tucker Taft 98-08-08
<<reference as: 1998-15877.a Tucker Taft 1998-8-8>>
!discussion

> What is the behavior of Ada.Task_Identification.Is_Callable for the
> environment task?
> In particular, does it change in value from True to False when the main
> subprogram
> exits and starts waiting for library-level tasks to terminate?

I believe it should.  Most of our compilers do the "right" thing,
but one does not.  Fixing this is not a big deal for us.  It was
just an oversight, and I agree that RM 10.2 gives enough hints
to imply that it should go from true to false upon return from
the main subprogram.

> ... If the task cannot sit on a terminate alternative (perhaps because
> it must poll a resource), a function which returns the status of the
> environment task is another solution - and Ada 95 already has the function.
>
> This problem has arisen in Claw in the task which handles Window messages,
> it is not academic.

This shows that making Is_Callable work "right" for the environment
task has value, and hence is worth enforcing.  Probably a simple
addition to one of the existing ACVC tests for Is_Callable could
resolve this, along with an appropriate AI, of course.

I presume other vendors will speak up if this is a major implementation
burden in some environments, in which case further discussion may be
necessary.

> 						Randy.

-Tuck

********************************************

!topic Is_Callable and the environment task.
!reference RM95-C.7.1(10);6.0
!reference RM95-C.7.1(21);6.0
!reference RM95-9.9(2);6.0
!reference RM95-9.3(5);6.0
!reference RM95-10.2(8);6.0
!reference RM95-10.2(25);6.0
!reference  1998-15876.a Randy Brukardt  1998-8-7
!from Ted Baker 1998-8-9
<<reference as: 1998-15878.a Ted Baker  1998-8-9>>
!discussion

| What is the behavior of Ada.Task_Identification.Is_Callable for
| the environment task?  In particular, does it change in value from
| True to False when the main subprogram exits and starts waiting
| for library-level tasks to terminate?

I believe the ARM intentionally leaves this unspecified.

...
| The value of Is_Callable would be useful to determine whether the main
| subprogram has completed.

I can see that it would be useful.
Without checking the code carefully, based on what I remember,
I guess GNARL would need some modification to give this behavior,
but it would not be a big change.

--Ted Baker

*******************************

!topic Is_Callable and the environment task.
!reference RM95-C.7.1(10);6.0
!reference RM95-C.7.1(21);6.0
!reference RM95-9.9(2);6.0
!reference RM95-9.3(5);6.0
!reference RM95-10.2(8);6.0
!reference RM95-10.2(25);6.0
!reference  1998-15876.a Randy Brukardt  1998-8-7
!reference  1998-15878.a Ted Baker  1998-8-9
<<reference as: 1998-15881.a Jean-Pierre Rosen 1998-8-11>>
!discussion
>
>| What is the behavior of Ada.Task_Identification.Is_Callable for
>| the environment task?  In particular, does it change in value from
>| True to False when the main subprogram exits and starts waiting
>| for library-level tasks to terminate?
>
>I believe the ARM intentionally leaves this unspecified.
>

I don't see what even makes you think that it is unspecified. OK, there is no
rule specifically saying what the behaviour of the environment task is, but
there are many places where special cases are not specified: it just means that
the regular rule applies.

This is enforced by C.7.1(21), a *note* (i.e. stressing something that can be
deduced from the RM), that says:
    The function Current_Task and the attribute Caller can return a Task_ID
    value that identifies the environment task.

I take "can" here as merely recognizing a fact, not as an option like "could" or
"might".


***********************************************************

!topic Is_Callable and the environment task.
!reference RM95-C.7.1(10);6.0
!reference RM95-C.7.1(21);6.0
!reference RM95-9.9(2);6.0
!reference RM95-9.3(5);6.0
!reference RM95-10.2(8);6.0
!reference RM95-10.2(25);6.0
!reference  1998-15876.a Randy Brukardt  1998-8-7
!reference  1998-15878.a Ted Baker  1998-8-9
!reference  1998-15881.a Jean-Pierre Rosen 1998-8-11
!from Ted Baker 1998-8-12
<<reference as: 1998-15882.a Ted Baker  1998-8-12>>
!discussion
|
| >| What is the behavior of Ada.Task_Identification.Is_Callable for
| >| the environment task?  In particular, does it change in value from
| >| True to False when the main subprogram exits and starts waiting
| >| for library-level tasks to terminate?
| >
| >I believe the ARM intentionally leaves this unspecified.
| >
| I don't see what even makes you think that it is unspecified....

Sorry, I was mistaken.  I see now that that the ARM '95 specifies
more than I remembered, i.e.,

| 10.2 Program Execution
...
| 10   The environment task for a partition has the following structure:
| 11  task Environment_Task;
| 12  task body Environment_Task is
|         ... (1) -- The environment declarative_part
|                 -- (that is, the sequence of library_items) goes here.
|     begin
|         ... (2) -- Call the main subprogram, if there is one.
|     end Environment_Task;
...
| 20   The sequence_of_statements of the environment task (see (2) above)
| consists of either:
|    21  A call to the main subprogram, if the partition has one.  If the
|        main subprogram has parameters, they are passed; where the
|        actuals come from is implementation defined.  What happens to the
|        result of a main function is also implementation defined.
| 22   or:
|    23  A null_statement, if there is no main subprogram.
...
| 9.9 Task and Entry Attributes
...
| 2   T'Callable
|                 Yields the value True when the task denoted by T is callable,
|                 and False otherwise;   a task is callable unless it is
|                 completed or abnormal.  The value of this attribute is of the
|                 predefined type Boolean.

--Ted




Questions? Ask the ACAA Technical Agent