From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!ukma!nrl-cmf!ames!elroy!cit-vax!ucla-cs!zen!ucbvax!IBM.COM!NCOHEN From: NCOHEN@IBM.COM (Norman COHEN) Newsgroups: comp.lang.ada Subject: More on terminate-but-stay-resident interrupt handlers Message-ID: <112387.161442.ncohen@ibm.com> Date: Tue, 24-Nov-87 14:33:07 EST Article-I.D.: ibm.112387.161442.ncohen Posted: Tue Nov 24 14:33:07 1987 Date-Received: Sat, 28-Nov-87 00:54:14 EST Sender: usenet@ucbvax.BERKELEY.EDU Organization: The ARPA Internet List-Id: I have three points to make regarding the discussion of terminate-but- stay-resident interrupt handlers: 1. As noted by cca!mirror!ishmael!ada-uts!stt@husc6.harvard.edu, "Despite the wording in the LRM, one of the language maintenance committee decisions somewhere along the way required that the tasks dependent on library packages be allowed to complete before the program as a whole was ended." The decision in question is AI-399. John Goodenough brought it to my attention after reading my suggestion for terminate-but-stay-resident interrupt handlers, noting that the AI "has been approved in essence at the WG9 and Ada Board level." AI-399 is a binding interpretation, i.e., a new rule. It changes LRM section 9.4 as follows: The "environment task" that invokes a main program (see 10.1(8)) is now considered the master of a library package. Among the consequences of this change are the following: a. Assuming that the environment task does nothing BUT call the main program (which is not stipulated by AI-399 but may be stipulated eventually by AI-222), the environment task becomes complete upon return from the main program. At this point, if all tasks declared in library packages are terminated or waiting at selective waits with terminate alternatives, these tasks and the environment task may terminate. (Thus, despite the words "hence not a library package" in 9.4(8), and despite my words to the contrary last week, a terminate alternative may be selected by a task declared in a library package.) b. As long as a task declared in a library package (e.g. an interrupt handler) has not terminated, the environment task cannot terminate, even if the main program has terminated. (The environment task remains complete, waiting for its dependent task to terminate.) Despite point (b), an implementation choosing to do so can allow terminate-but-stay-resident interrupt handlers to be written in the way I described last week: The handlers can be written as tasks declared in library packages and specified by means of implementation-defined pragmas to be terminate-but-stay-resident tasks. The word "terminated" has two different meanings in this context: One is the Ada meaning, subject to the rules in 9.4 about when tasks terminate. The other is the operating-system meaning captured in the phrase "terminate but stay resident." The two meanings need not coincide. In appropriate circumstances, such as when the dependent tasks of the completed environment task are interrupt handlers and require no explicit scheduling, an implementation can treat an environment task that is completed but not yet terminated (in the Ada sense) as an application that has terminated (in the operating-system sense) but remained resident. For example, an interactive user of the operating system would see a new prompt and would be able to spawn a new environment task executing a new main program even though the previous environment task was technically still executing. Truth-in-tasking (a companion to truth-in-packaging) requires me to relate the following recommendation contained in AI-399: It is recommended that implementations targetted to conventional time-sharing operating systems define the environment task as being created and activated when Ada program execution is initiated by operating system command, and that termination of the environment task occur before control is returned to the command interpreter. It is up to the implementation to define the environment task in an appropriate manner for the target environment. Please note, however, the words "It is recommended" (not required by the binding interpretation) and the admission in the next sentence that the implementer is the ultimate judge of what is appropriate in a given environment. The Unix shell, for example, spawns a subshell to execute a command line ending with an &, and does not wait for the "environment task" executing the command to complete before prompting for a new command line. Surely the recommendation in AI-399 would not apply in such a context. 2. Dave Emery objects, "...it seems to me that this is potentially erroneous, in that the language does not define...what would happen in this instance (i.e. isn't this implementation dependent)." Yes, it is unabashedly implementation-dependent. The notion of terminate- but-stay-resident programs is implementation-dependent, so any Ada scheme to implement them must be implementation-dependent. No, it is not erroneous. The term "erroneous" is narrowly defined by the LRM to refer to twelve specific ways that a program can violate the rules of Ada without (necessarily) being caught either by the compiler or by run-time checks. Nonportable programming is to be avoided if it can be (it can't be in the case of terminate-but-stay-resident interrupt handlers); but unlike erroneous execution, nonportable programming does not necessarily violate any rules of the Ada language. This erroneous use of the term "erroneous" is quite prevalent. I have an article on this matter in the pipeline to Ada Letters. 3. Concerning the interaction between terminate alternatives and interrupt entries, which was the real subject of Dave's original query: The rules in 9.4 defining masters and dependents and stipulating when a terminate alternative could be selected were intended to ensure that a task T could select a terminate alternative only when all tasks able to name T in an entry call were themselves terminated or waiting at selective waits with terminate alternatives. (Alas, a loophole was later discovered, but this was the intent.) It was believed that, as a consequence of the definition of a master and its relation to the scope rules, a task could be named only from within its master or some task dependent on its master. This reasoning does not apply to tasks with interrupt entries, because a "hardware task" that calls an interrupt entry (see 13.5.1(2)) is not subject to Ada scope rules; it can call an interrupt entry without being able to name the called task. That is why 13.5.1(3) states that, when an accept statement for an interrupt entry and a terminate alternative occur in the same selective wait, "an implementation may impose further requirements for the selection of the terminate alternative in addition to those given in section 9.4." (The loophole involves a function returning a task object declared within the function. The function is the task's master. If the task has a terminate alternative, the alternative becomes selectable as soon as the function executes its return statement, and the function then returns. If a call on the function occurs as the prefix in an entry call, then an entry of the task returned by the function is called after that task has selected a terminate alternative. The entry call raises Tasking_Error.)