F.Zwarts@KVI.NL ("Fred Zwarts, KVI, Groningen, NL.") (02/23/90)
Hello all, I am rather new to Ada and I am not quite sure that this is the right place to ask, but I do not know a better place. I am uncertain about the interpretation of LRM 13.10.1(8) on the UNCHECKED_DEALLOCATION procedure, where I read: "If X designates a task object, the call FREE(X) has no effect on the task ...". My question is: What means "no effect"? Suppose X designates a terminated task, see LRM 9.4(6-10). Can FREE(X) be used to reclaim memory held by such a terminated task, like a task control block? Does the LRM allow such an interpretation? If this interpretation is not allowed, I can imagin a case in which one runs out of memory because of a large amount of terminated tasks. If always at least one such task is running, it is not possible to leave the block in which the declaration of X's type was elaborated LRM 9.4(6), which could otherwise be a way to reclaim memory. Fred Zwarts E-mail: INFOADA@KVI.nl Kernfysisch Versneller Instituut 9747 AA Groningen The Netherlands
madmats%elcit.epfl.ch@vma.cc.cmu.edu (Mats Weber) (02/27/90)
>I am rather new to Ada and I am not quite sure that this is the right place to >ask, but I do not know a better place. It is the right place to ask. >I am uncertain about the interpretation of LRM 13.10.1(8) on the >UNCHECKED_DEALLOCATION procedure, where I read: >"If X designates a task object, the call FREE(X) has no effect on the task >...". >My question is: What means "no effect"? >Suppose X designates a terminated task, see LRM 9.4(6-10). >Can FREE(X) be used to reclaim memory held by such a terminated task, like a >task control block? Does the LRM allow such an interpretation? The LRM says nothing about the deallocation of the working storage (stack space, etc.) of tasks. Most implementations I know of reclaim that storage when the block that declares the corresponding task type is left, but this behaviour is not required by the LRM. "no effect" means that calling Free(X) does not affect the execution of the designated task, in particular, the designated task does not stop and must still terminate before its master can be exited. Free(X) simply makes the designated task inaccessible. >If this interpretation is not allowed, I can imagin a case in which one runs >out of memory because of a large amount of terminated tasks. If always at least >one such task is running, it is not possible to leave the block in which the >declaration of X's type was elaborated LRM 9.4(6), which could otherwise be a >way to reclaim memory. You are right. Most implementations do not reclaim the stack storage of terminated tasks. A workaround is to put these unused tasks into a pool and reuse them, allocating new tasks only when the pool is empty. Mats Weber Swiss Federal Institute of Technology EPFL DI LGL 1015 Lausanne Switzerland E-mail : madmats@elcit.epfl.ch phone : +41 21 693 52 92 fax : +41 21 693 22 20
NCOHEN@IBM.COM ("Norman H. Cohen") (02/27/90)
13.10.1(8) is one of the most often misinterpreted paragraphs in the RM. (Fortunately, it's a note, and therefore not officially part of the language definition. LRM 2.7(1) states, "Furthermore, comments do not influence the effect of a program; their sole purpose is the enlightenment of the human reader." John Goodenough once quipped that the LRM Note paragraphs do not influence the definition of the language; their sole purpose is to confuse the reader.) There are two sources of confusion: 1. Informally, we often use the word "task" to mean a task unit or a task object. However, in the (usually) precise language of the LRM, a "task" in Ada is neither an object nor a program unit, but a process (a thread of control). A TASK OBJECT "designates" some task. (See 9(2) and 9.2(2).) 2. The word "designates" also has another technical meaning in the LRM: An access value "designates" the object it points to (see 3.8(1)). Unfortunately, the word "designates" is used in both senses in the first sentence of 13.10.1(8). Now lets look at the first sentence of 13.10.1(8): If X designates a task object, the call FREE(X) has no effect on the task designated by the task object. (Here X is an access value and FREE is an instance of UNCHECKED_DEALLOCATION.) An informal paraphrase is: If X points to a task object, the call FREE(X) has no effect on the thread of control corresponding to that task object. Thus, for example, you can't abort a task by attempting to deallocate it. When an instance of UNCHECKED_DEALLOCATION is applied to a task object designating a terminated task, a good compiler will reclaim the storage occupied by the task object. Not all compilers are good. Norman H. Cohen
jcallen@Encore.COM (Jerry Callen) (02/27/90)
In article <foo> F.Zwarts@KVI.NL ("Fred Zwarts, KVI, Groningen, NL.") writes: >I am uncertain about the interpretation of LRM 13.10.1(8) on the >UNCHECKED_DEALLOCATION procedure, where I read: > >"If X designates a task object, the call FREE(X) has no effect on the task >...". > >My question is: What means "no effect"? >Suppose X designates a terminated task, see LRM 9.4(6-10). >Can FREE(X) be used to reclaim memory held by such a terminated task, like a >task control block? Does the LRM allow such an interpretation? The "no effect" statement means that freeing a task object won't do something unpleasant to it (like free its stacks/control blocks out from under it). You can't really reclaim ALL of the storage associated with a task until the task's scope disappears, even in the case of a task created with an allocator; there may be other copies of the pointer floating around, and the owners of those copies may (erroneously) query the 'CALLABLE/'TERMINATED attributes of the task. You could argue that, by using Unchecked_Deallocation, you are explicitly telling the RTS that there are no dangling pointers, but I think it's safer for the RTS to assume that there might be. Note that a clever implementation will release nearly all of the storage associated with a task (stacks, most control blocks, etc.) at task completion; all that really has to hang around is a stub of the TCB that can be used to implement the above attributes. >If this interpretation is not allowed, I can imagin a case in which one runs >out of memory because of a large amount of terminated tasks. If always at least >one such task is running, it is not possible to leave the block in which the >declaration of X's type was elaborated LRM 9.4(6), which could otherwise be a >way to reclaim memory. Hopefully your RTS is going to free as much storage as it can at task completion. Trying to "help it" with Unchecked_Deallocation is probably useless. >Fred Zwarts E-mail: INFOADA@KVI.nl >Kernfysisch Versneller Instituut >9747 AA Groningen >The Netherlands -- Jerry Callen jcallen@encore.com (508) 460-0500
Loren@cup.portal.com (Loren Louis Hart) (02/28/90)
In his artical about LRM 13.10.1 Fred Zwarts writes: >Hello all, >I am rather new to Ada and I am not quite sure that this is the right place to >ask, but I do not know a better place. This is exactly the right place for this question. It is much better than the "My language is better than your language" discussion that has been apearing in this news group lately. >I am uncertain about the interpretation of LRM 13.10.1(8) on the >UNCHECKED_DEALLOCATION procedure, where I read: > >"If X designates a task object, the call FREE(X) has no effect on the task >...". > >My question is: What means "no effect"? >Suppose X designates a terminated task, see LRM 9.4(6-10). >Can FREE(X) be used to reclaim memory held by such a terminated task, like a >task control block? Does the LRM allow such an interpretation? Has no effect means exactly what it says. The program behaves the same in all respects if it is there or not. It will be the same (other than maybe efficiency) as if the compiler generated no code. My understanding is that a task is an object, you can deallocate objects, it is potentially confusing and dangerious to allow someone to deallocate a task. The choice is either to ignore the request or generate an error; in this case they decided the request should be ignored. >If this interpretation is not allowed, I can imagin a case in which one runs >out of memory because of a large amount of terminated tasks. If always at leas t >one such task is running, it is not possible to leave the block in which the >declaration of X's type was elaborated LRM 9.4(6), which could otherwise be a >way to reclaim memory. Most implementations (all that I know about) deallocate all of the memory that a task uses upon termination. The only exception is sometimes the fairly small entry for that task that indicates if the task is running and where to find its memory is kept around. Loren L. Hart loren@cup.portal.com San Jose, California
stt@inmet.inmet.com (03/03/90)
With regard to reclaiming storage for a terminated task: It is useful to distinguish between a "task object" and a "task". A "task object" designates a task. An access type designates a task object (or a record/array object containing a task object). When you perform an unchecked deallocation, the space for the task object may be reclaimed, and it is erroneous if some other access value is later used to try to refer to this task object. Therefore, it *is* legitimate for an implementation to free *all* storage associated with a terminated *task* when the task object is freed (Sorry not to agree with you Jerry!). However, it is *not* legitimate to free the storage associated with a task with live sub-tasks (i.e. "completed" but not "terminated"), nor is it permissible to implicitly abort a non-completed task when its task object is freed. Using a relatively simple trick, it is actually possible to free the space devoted to a task as soon as it terminates, even if its task object still exists. The trick is to store a "generation number" within the task control block, and bump that number when reusing the TCB for a new task. The same generation number is stored with the task object, and a task is considered terminated if the generation number in its task object doesn't match the generation number in the TCB it points at. By the way, the ARG (Ada Rapporteur(sp?) Group) recently decided to reverse an earlier decision, and consider a reference to a task outside of its scope as erroneous (the dreaded task-returning function problem). This means that TCBs can be reclaimed when the task object's scope is exited, at the latest. S. Tucker Taft stt%inmet@uunet.uu.net; uunet!inmet!stt Intermetrics, Inc. Cambridge, MA 02138
jbg@sei.cmu.edu (John Goodenough) (03/06/90)
In article Re: Interpretation of LRM 13.10.1 of 2 Mar 90 18:21:00 GMT stt@inmet.inmet.com writes: > By the way, the ARG (Ada Rapporteur(sp?) Group) recently decided to reverse > an earlier decision, and consider a reference to a task > outside of its scope as erroneous (the dreaded task-returning function > problem). Just a reminder that the ARG does not have the last word on interpreting the Standard. ARG decisions are subject to review at higher approval levels and are not definitive until approved by ISO WG9 (responsible for the ISO Ada Standard) and the AJPO (responsible for the ANSI standard). Although I would not expect the decision on functions returning tasks to be reversed after further review, ARG decisions have in the past been reversed in response to objections. John B. Goodenough Goodenough@sei.cmu.edu Chair, ARG Software Engineering Institute 412-268-6391 -- John B. Goodenough Goodenough@sei.cmu.edu Software Engineering Institute 412-268-6391