comp.lang.ada
 help / color / mirror / Atom feed
* Task deallocation
@ 1997-02-11  0:00 Jonas Nygren
  1997-02-12  0:00 ` Mats Weber
  0 siblings, 1 reply; 7+ messages in thread
From: Jonas Nygren @ 1997-02-11  0:00 UTC (permalink / raw)



I have a problem related to freeing tasks, that I can't find a good
solution to. Here follows a short description of my problem.

I am doing a server-task that dynamically allocates sub-tasks to handle
individual requests. I want the sub-tasks to use a terminate alternative
so that they terminate when the server-task is terminated. My problem is
how to reclaim the storage for the sub-tasks. One possible alternative is
to have a linked list of the sub-tasks outside of the-server task and then
scan this list of sub-tasks for terminated tasks and delete them,
recursively
until the list is empty. This code looks a bit on the heavy side and maybe
there is an easier way to reclaim the storage used by these tasks.

Anybody have any good suggestions of a better alternative to the solution I
described above? Any suggestions are welcome.

/jonas

PS If the sub-task type were defined inside the server-task then it should
   be possible for the Ada RT to automagically free the sub-tasks after the
   the termination of the server-task since they cannot be referenced by 
   any other entity. I have read the Ada RM but I cannot find anything on 
   this topic (except that it is an error to free a non-terminated task). DS




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Task deallocation
  1997-02-11  0:00 Task deallocation Jonas Nygren
@ 1997-02-12  0:00 ` Mats Weber
  0 siblings, 0 replies; 7+ messages in thread
From: Mats Weber @ 1997-02-12  0:00 UTC (permalink / raw)



> I am doing a server-task that dynamically allocates sub-tasks to handle
> individual requests. I want the sub-tasks to use a terminate alternative
> so that they terminate when the server-task is terminated. My problem is
> how to reclaim the storage for the sub-tasks. One possible alternative is
> to have a linked list of the sub-tasks outside of the-server task and then
> scan this list of sub-tasks for terminated tasks and delete them,
> recursively
> until the list is empty. This code looks a bit on the heavy side and maybe
> there is an easier way to reclaim the storage used by these tasks.
> 
> Anybody have any good suggestions of a better alternative to the solution I
> described above? Any suggestions are welcome.
> 
> /jonas
> 
> PS If the sub-task type were defined inside the server-task then it should
>    be possible for the Ada RT to automagically free the sub-tasks after the
>    the termination of the server-task since they cannot be referenced by
>    any other entity. I have read the Ada RM but I cannot find anything on
>    this topic (except that it is an error to free a non-terminated task). DS

You can arrange for the server to be the master of the sub-tasks (even
if the sub-task type is declared in another library package) in the
following way:

package Subtasks is
   task type T is
      entry E;
      -- has a terminate alternative.
   end T;
end Subtasks;

with Subtasks;

procedure Server is

   type Subtask_Access is access Subtasks.T;
      -- Tasks created by allocators of this access type
      -- will have Server as master.

begin
   ... := new Subtasks.T;
end Server;

When the server finishes, it will wait for all subtasks to terminate,
and thus their terminate alternatives will be open. If one or more of
the subtasks are not ready to terminate, then Server will not exit.
Note: Server can be the main program, or it can be called from another
program unit.




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Task deallocation
@ 1997-02-23  0:00 Jonas Nygren
  1997-02-28  0:00 ` Mats Weber
  0 siblings, 1 reply; 7+ messages in thread
From: Jonas Nygren @ 1997-02-23  0:00 UTC (permalink / raw)




I sent out a question about how to deallocate dynamically allocated tasks.
There were some answers from which I learnt that deallocating new'd tasks
was perhaps not so straightforward as I believed. 

Apparently most compilers represents a task by a pointer to some internal
structure. If this internal storage is not reclaimed when a task is 
deallocated one will have a storage leak. 

So my question is how to deallocate a dynamically allocated task without
creating a memory leak. 

If I call Free for a dynamically allocated task will this ensure that the
internal storage structures for tasks are reclaimed? E.g.:

	type My_Task_Ref is access My_Task;
	procedure Free is new Unchecked_Deallocation(My_Task, My_Task_Ref);
	MTR : My_Task_Ref := new My_Task;
	...
	Free(MTR); -- assume MTR'Terminated is true
	-- will the internal task structures have been reclaimed??

or will it just reclaim the pointer that the compiler use to represent 
the instance of My_Task.

My guess is that the example above will result in a storage leak. Mats
Weber 
suggested that the only portable solution to handle deallocation of tasks 
is to put them on a global free-list instead of deallocating them.

Is there really no portable way to deallocate dynamically allocated tasks 
without storage leaks? 

/jonas





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Task deallocation
  1997-02-23  0:00 Jonas Nygren
@ 1997-02-28  0:00 ` Mats Weber
  1997-03-01  0:00   ` Robert Dewar
  0 siblings, 1 reply; 7+ messages in thread
From: Mats Weber @ 1997-02-28  0:00 UTC (permalink / raw)



Jonas Nygren wrote:
> 
> I sent out a question about how to deallocate dynamically allocated tasks.
> There were some answers from which I learnt that deallocating new'd tasks
> was perhaps not so straightforward as I believed.
> 
> Apparently most compilers represents a task by a pointer to some internal
> structure. If this internal storage is not reclaimed when a task is
> deallocated one will have a storage leak.
> 
> So my question is how to deallocate a dynamically allocated task without
> creating a memory leak.
> 
> If I call Free for a dynamically allocated task will this ensure that the
> internal storage structures for tasks are reclaimed? E.g.:
> 
>         type My_Task_Ref is access My_Task;
>         procedure Free is new Unchecked_Deallocation(My_Task, My_Task_Ref);
>         MTR : My_Task_Ref := new My_Task;
>         ...
>         Free(MTR); -- assume MTR'Terminated is true
>         -- will the internal task structures have been reclaimed??

On a reasonable implementation, all memory will be reclaimed when the
task terminates.

Ada 95 (in 13.11.2) says it is an error to deallocate an unterminated
discriminated task object, but doesn't say anything on deallocating a
non-discriminated task object. Could anyone clarify this ?

But note that it is not so easy to make sure that the task is terminated
when you call Free, for instance:

task type my_task is
   entry E;
   entry Done;
end;

task body my_task is
begin
   loop
      accept E;
      exit when ...;
   end loop;
   accept Done;
end;

...

MTR.Done;
Free(MTR);

It is not certain that MTR.all'Terminted is true when Free is called
(the task can still be between "accept Done" and "end"). To be
absolutely sure, you must write

MTR.Done;
begin
   MTR.Done;
exception
   when Tasking_Error =>
      Free(MTR);
end;

which is quite ugly.

In Ada 83, freeing a non-terminted task object did not affect the task
itself and I have never had a problem doing so in programs (particularly
in the above situation). Has this been changed in Ada 95 ?

> Is there really no portable way to deallocate dynamically allocated tasks 
> without storage leaks? 

Strictly speaking, there is no portable way of deallocating _any_ memory
in Ada when you use standard storage pools. The fact that
Unchecked_Deallocation effectively deallocates is just an implementation
advice. But all reasonable implementations will effectively deallocate,
and this should also hold for task memory.

Making memory management non-mandatory is quite reasonable if you
consider that Ada should also be able to run on embedded CPUs with very
little memory where dynamic allocation would not be used and would only
increase the size of the run time system.

On the other hand, a compiler for UNIX will be very hard to sell if
Unchecked_Deallocation does not work (except if it has a garbage
collector).




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Task deallocation
  1997-02-28  0:00 ` Mats Weber
@ 1997-03-01  0:00   ` Robert Dewar
  1997-03-03  0:00     ` Mats Weber
  0 siblings, 1 reply; 7+ messages in thread
From: Robert Dewar @ 1997-03-01  0:00 UTC (permalink / raw)



Mats said

<<On a reasonable implementation, all memory will be reclaimed when the
task terminates.>>

Probably this is false, think about the implementation of the 'Terminated
query, certainly you cannot assume it is true.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Task deallocation
  1997-03-01  0:00   ` Robert Dewar
@ 1997-03-03  0:00     ` Mats Weber
  1997-03-04  0:00       ` Robert Dewar
  0 siblings, 1 reply; 7+ messages in thread
From: Mats Weber @ 1997-03-03  0:00 UTC (permalink / raw)



> <<On a reasonable implementation, all memory will be reclaimed when the
> task terminates.>>
> 
> Probably this is false, think about the implementation of the 'Terminated
> query, certainly you cannot assume it is true.

OK. How is it done in GNAT ?

Do you think that the approach of keeping a pool of unused tasks of each
task type for later recycling (as I suggested earlier in this thread,
i.e. 'manual', self-programmed memory management) is still necessary
with modern Ada 95 compilers ?




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Task deallocation
  1997-03-03  0:00     ` Mats Weber
@ 1997-03-04  0:00       ` Robert Dewar
  0 siblings, 0 replies; 7+ messages in thread
From: Robert Dewar @ 1997-03-04  0:00 UTC (permalink / raw)



<<Do you think that the approach of keeping a pool of unused tasks of each
task type for later recycling (as I suggested earlier in this thread,
i.e. 'manual', self-programmed memory management) is still necessary
with modern Ada 95 compilers ?>>

It's a good idea in any case, because that way you avoid the task creation
and destruction overhead, which can be significant in many systems.





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~1997-03-04  0:00 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-02-11  0:00 Task deallocation Jonas Nygren
1997-02-12  0:00 ` Mats Weber
  -- strict thread matches above, loose matches on Subject: below --
1997-02-23  0:00 Jonas Nygren
1997-02-28  0:00 ` Mats Weber
1997-03-01  0:00   ` Robert Dewar
1997-03-03  0:00     ` Mats Weber
1997-03-04  0:00       ` Robert Dewar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox