[comp.lang.ada] Lingering task control blocks

wilson%anchor.DECnet@lll-icdc.arpa ("ANCHOR::WILSON") (12/30/86)

I've run into an implementation problem which bothers me.  I'm using VAX
Ada V1.3 on a VAX 11/750.

I have a generic package which is used to manage network logical links (an 
implementation of task-to-task communications).  The package imports a
generic procedure parameter

	HANDLE_MESSAGE(
		FROM	: in ADDRESS_TYPE;
		MESSAGE : in MESSAGE_TYPE
			)

This procedure is called every time a message is received from any of the 
links.

It is expected that during a run of the program there will be arbitrarily
many logical links, but there won't be more than a few at any single
instant. 

My initial design called for a reader task for each link.  I can create a
copy of the task whenever a link is established, and I can let the task
terminate naturally when the link is closed. 

The problem I ran into is that when the reader tasks terminate, its task 
control block space is not deallocated.  I haven't found a statement in the 
RM stating that it should or should not be, but in the DEC "VAX Ada 
Programmer's Run-Time Reference Manual," section 7.2.1, they say that 

 	"the task control block is released when control leaves 
	the immediate master (another task or a currently 
	executing block or subprogram) upon which the task depends
	--not when the task terminates."

Now the RM states (4.8(6))

	"Moreover, if an object . . . belongs to a task type, it is 
	considered to be accessible as long as the task is not
	terminated.  An implementation may (but need not) reclaim
	the storage occupied by an object created by an allocator,
	once this object has become inaccessible."

The RM goes on to state inform you that you can use UNCHECKED_DEALLOCATION 
if you require "closer control" over storage allocation.  Unfortunately, it
also states (13.10.1(8)) that

	"If X designates a task object, the call FREE(X) has no effect
	on the task designated by the value of this task object."

I suppose this says that it won't free the task control block, although I'm 
not certain as to the scope of the RM's statement.

The problem with letting the run-time system handle the deallocation is 
that I can't write the program to leave the scope of the master since there 
will almost always be a reader task running.  I can't explicitely FREE the 
space because UNCHECKED_DEALLOCATION won't do anything to tasks.  

As a work-around, I wrote a DISPATCHER task, and I wrote the reader tasks
so that after finishing work on one logical link they go back to the
DISPATCHER for re-use.  I don't like this for a few reasons:

	1)  It's more complicated.
	2)  I liked the idea of having a task whose life mimicked the
	    life of the logical link.  I liked knowing that the state
	    of the task started out fresh everytime a new link was created.

Number 2 is the one that bothers me the most.  There are several other 
places in our system where our state transition diagrams map neatly to task 
bodies, and putting in DISPATCHERs all over the place really messes things 
up.

My questions, I guess, are these:

	1)  Have I read the situation right with the DEC compiler?
	2)  Did DEC miss a bet when choosing not to free up task
	    control block space when the task is terminated?
	3)  Is there some subtle reason why it's easier to wait until
	    control has left the immediate master?
	4)  Do other compilers do it the same way, or are there some that
	    free up the control block space when the task terminates?

Thanks for your time,

			--- Rick Wilson

wilson%anchor.decnet@lll-icdc.arpa
(415) 423-6662
------

wilson%anchor.DECnet%lll-icdc.arpa%taurus.BITNET@WISCVM.WISC.EDU ("ANCHO) (12/30/86)

I've run into an implementation problem which bothers me.  I'm using VAX
Ada V1.3 on a VAX 11/750.

I have a generic package which is used to manage network logical links (an
implementation of task-to-task communications).  The package imports a
generic procedure parameter

        HANDLE_MESSAGE(
                FROM    : in ADDRESS_TYPE;
                MESSAGE : in MESSAGE_TYPE
                        )

This procedure is called every time a message is received from any of the
links.

It is expected that during a run of the program there will be arbitrarily
many logical links, but there won't be more than a few at any single
instant.

My initial design called for a reader task for each link.  I can create a
copy of the task whenever a link is established, and I can let the task
terminate naturally when the link is closed.

The problem I ran into is that when the reader tasks terminate, its task
control block space is not deallocated.  I haven't found a statement in the
RM stating that it should or should not be, but in the DEC "VAX Ada
Programmer's Run-Time Reference Manual," section 7.2.1, they say that

        "the task control block is released when control leaves
        the immediate master (another task or a currently
        executing block or subprogram) upon which the task depends
        --not when the task terminates."

Now the RM states (4.8(6))

        "Moreover, if an object . . . belongs to a task type, it is
        considered to be accessible as long as the task is not
        terminated.  An implementation may (but need not) reclaim
        the storage occupied by an object created by an allocator,
        once this object has become inaccessible."

The RM goes on to state inform you that you can use UNCHECKED_DEALLOCATION
if you require "closer control" over storage allocation.  Unfortunately, it
also states (13.10.1(8)) that

        "If X designates a task object, the call FREE(X) has no effect
        on the task designated by the value of this task object."

I suppose this says that it won't free the task control block, although I'm
not certain as to the scope of the RM's statement.

The problem with letting the run-time system handle the deallocation is
that I can't write the program to leave the scope of the master since there
will almost always be a reader task running.  I can't explicitely FREE the
space because UNCHECKED_DEALLOCATION won't do anything to tasks.

As a work-around, I wrote a DISPATCHER task, and I wrote the reader tasks
so that after finishing work on one logical link they go back to the
DISPATCHER for re-use.  I don't like this for a few reasons:

        1)  It's more complicated.
        2)  I liked the idea of having a task whose life mimicked the
            life of the logical link.  I liked knowing that the state
            of the task started out fresh everytime a new link was created.

Number 2 is the one that bothers me the most.  There are several other
places in our system where our state transition diagrams map neatly to task
bodies, and putting in DISPATCHERs all over the place really messes things
up.

My questions, I guess, are these:

        1)  Have I read the situation right with the DEC compiler?
        2)  Did DEC miss a bet when choosing not to free up task
            control block space when the task is terminated?
        3)  Is there some subtle reason why it's easier to wait until
            control has left the immediate master?
        4)  Do other compilers do it the same way, or are there some that
            free up the control block space when the task terminates?

Thanks for your time,

                        --- Rick Wilson

wilson%anchor.decnet@lll-icdc.arpa
(415) 423-6662
------