comp.lang.ada
 help / color / mirror / Atom feed
* Dynamic allocation of tasks
@ 2000-03-22  0:00 Florian Weimer
  2000-03-22  0:00 ` Robert Dewar
  0 siblings, 1 reply; 10+ messages in thread
From: Florian Weimer @ 2000-03-22  0:00 UTC (permalink / raw)


Dynamically allocating tasks isn't really a problem, but deallocating
them is. :-/

I found no way to complete a task before its allocator completes.
Most of the time, this is a good thing.  But if you are allocating
tasks using an allocator for a library-level access type, you'll almost
certainly run into problems, because these tasks won't complete until the
program terminates.  There are workarounds, of course, and I'll describe
two of them below.  If you know different ones, I'd be glad if you could
share them; I'm going to add a summary to the FAQ at www.adapower.com
(if David Botton agrees).


First Solution: Static allocation

This solution uses an approach comparable to a typical implementation
of Ada.Strings.Bounded.  Of course, this simple solution isn't possible
in all cases.  Code example:

   task type Some_Task;
   type Task_Array is array (Positive range <>) of Some_Task;

   type Dynamic_Tasks_Type (Number_Of_Tasks : Natural) is record
      Tasks : Task_Array (1 .. Number_Of_Tasks);
      Last_Allocated_Task : Natural := 0; -- an index into Tasks
   end record;

Some_Task typically has got some kind of start entry, so that superfluous
elements in Tasks which aren't really used cause no harm (besides
unnecessary resource consumption).

This approach gets more and more clumsy if you've got more than one
task type because you have to specify each task count individually.


Second Solution: Localize the access type used to allocate tasks

The idea behind this is that an access type which is declared locally
doesn't cause the problems of a library-level one.  This is not always
directly possible, e.g. in the following pseudocode (which uses a
hypothetical package Dynamic_Tasks which allocates tasks dynamically):

   Dynamic_Tasks.Allocates_Tasks_As_Side_Effect;
   Dynamic_Tasks.Allocates_More_Tasks_As_Side_Effect;

   Dynamic_Tasks.Do_Something_With_These_Tasks;
   Dynamic_Tasks.Do_Something_Else;

   Dynamic_Tasks.Wait_For_These_Tasks;

All these functions must access the allocated tasks, and they have to
use an access of a type declared in the enclosing package for that.

Usually, this access type is located at the library level, but if you
make the package a generic one, this is no longer the case.  The drawback
of this solution: It might result in severe code bloat if the compiler
doesn't support shared generics.

In order to avoid this code bloat, one could declare in a generic
subprogram the access type whose allocator is used to allocate the tasks.
The operations listed in the example would be placed into a local
subprogram, and this subprogram would be passed as actual parameter to
the generic subprogram instantiation.




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

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

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-22  0:00 Dynamic allocation of tasks Florian Weimer
2000-03-22  0:00 ` Robert Dewar
2000-03-22  0:00   ` Florian Weimer
2000-03-22  0:00     ` Lutz Donnerhacke
2000-03-22  0:00       ` Florian Weimer
2000-03-27  0:00         ` Robert A Duff
2000-03-28  0:00           ` Florian Weimer
2000-03-28  0:00             ` Tucker Taft
2000-03-23  0:00     ` Robert Dewar
2000-03-24  0:00       ` Florian Weimer

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