comp.lang.ada
 help / color / mirror / Atom feed
From: NCOHEN@IBM.COM (Norman Cohen)
Subject: Deallocation of T'STORAGE_SIZE for a terminated task
Date: 22 Sep 88 13:21:48 GMT	[thread overview]
Message-ID: <092288.092151.ncohen@ibm.com> (raw)

Ref: INFO-ADA Digest Volume 88 Issue 200 (Thu, Sep 22, 1988) Item #2

Consider the following program:

     PROCEDURE Main IS

        TYPE Work_Item_Type IS ...;

        TASK TYPE Work_Processor_Type IS
           ENTRY Assign_Work (Work: IN Work_Item_Type);
        END Work_Processor_Type;

        TYPE Work_Processor_Pointer_Type IS ACCESS Work_Processor_Type;

        Work_Item          : Work_Item_Type;
        New_Work_Processor : Work_Processor_Pointer_Type;

        PROCEDURE Deallocate_Work_Processor IS
           NEW Unchecked_Deallocation
              (Work_Processor_Type, Work_Processor_Pointer_Type);

        TASK BODY Work_Processor_Type IS SEPARATE;
        PROCEDURE Wait_For_Work (Work_Item: OUT Work_Item_Type);

     BEGIN

        LOOP
           Wait_For_Work (Work_Item);
           New_Work_Processor := NEW Work_Processor_Type;
           New_Work_Processor.Assign_Work (Work_Item);
           Deallocate_Work_Processor (New_Work_Processor);
        END LOOP;

     END Main;

Work processors are assigned as work items arrive.  Several work
processors may be active simultaneously, asynchronously processing their
assigned work items.  The intent of the last statement in the loop is
to deallocate storage for each work-processor task when it completes its
work, so that the storage may be used for other work processors.

If the task allocated in the third statement of the loop completes its
work and terminates before the main program advances to the fourth
statement in the loop, we would expect the storage for the task object
to be reclaimed as for an allocated object of any other type.  However,
if (as is likely) the task is still active when the fourth statement of
the loop is reached, the call on Deallocate_Work_Processor
has no effect on the task.  (In particular, the task is not aborted so
that storage for the task object can be reclaimed.)  That is the point of
Reference Manual paragraph 3.10.1(8) (which is a note, not a rule).

There are several options available to the friendly designer of a run-
time system, and several recourses available to the user whose run-time-
system designer was not inclined to be friendly.

First, we must distinguish between two kinds of storage associated with
tasks, the task control block (data maintained by the run-time system
for such purposes as task scheduling and task communication) and the
task stack (used for application data local to the task body or local to
subprograms invoked by the task).  A typical implementation has a task
object corresponding to a task control block and a representation clause
for T'Storage_Size, where T is a task type, determining the size of the
stack allocated when a task of the type is activated.

Options available to the friendly designer of a run-time system include:

- Deallocating the task stack (Work_Procesor_Type'Storage_Size bytes)
  immediately upon task termination, even if the task control block
  (Work_Processor_Type'Size bits) must remain in existence for such
  purposes as evaluating the 'Terminated attribute or raising
  Tasking_Error in any other task that calls an entry of the terminated
  task.

- Implementing a task object as a pointer to a task control block, but
  representing the task object of a terminated task by a null pointer and
  deallocating storage for the task control block itself as soon as the
  task has terminated.

- Automatically reclaiming storage for allocated task objects as soon as
  the task has terminated, provided that the task object is no longer
  accessible by access values.  (This is a restricted form of incremental
  garbage collection in which reference counts can be used.)

- Having instances of Unchecked_Deallocation set a "deallocation pending"
  flag in the task control block if the task objects for which
  deallocation was requested designate still-active tasks.  Upon
  termination, the task control block would be deallocated if its
  "deallocation pending" flag were set.

Options available to the user of a run-time system whose designer was not
inclined to be friendly include the following:

- Introduce another task, of low-priority, to explicitly manage
  allocation and deallocation of task objects.  Thus the assignment

     New_Work_Processor := NEW Work_Processor_Type;

  in the program above would be replaced by an entry call on this new
  task:

     Work_Processor_Manager.Get_New_Task (New_Work_Processor);

  The low-priority task would maintain a list of currently allocated
  tasks and periodically query the 'Terminated attribute of tasks on the
  list, deallocating a task object and removing the pointer to that
  object from the list whenever the designated task is found to be
  terminated.

- If there is a known maximum on the number of work processors that will
  be active simultaneously, declare an array of that many
  Work_Processor_Type objects.  Add an entry, called once at program
  start-up, to tell a Work_Processor_Type task its index within this
  array.  Declare a list of indices of currently idle tasks, initialized
  to a list containing every task index.  Modify the Work_Processor_Type
  task body so that, rather than terminating when it is done with its
  work, it adds its index to the list of indices of idle tasks and loops
  back to its Assign_Work entry to wait for more work.  The assignment
  statement allocating a new task would be replaced by a statement
  removing the first idle-task index from the list, then calling the
  Assign_Work entry of the corresponding array element.

Norman Cohen
IBM Research

             reply	other threads:[~1988-09-22 13:21 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1988-09-22 13:21 Norman Cohen [this message]
  -- strict thread matches above, loose matches on Subject: below --
1988-09-21 13:36 Deallocation of T'STORAGE_SIZE for a terminated task Frank Prindle
replies disabled

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