[comp.lang.ada] Problems with creating large number of tasks that utilize re-entrant code

asheem@cwruecmp.UUCP (03/09/87)

Hi,

   I am involved in a project that deals with the simulation
of a MAP factory communications network. We are using Ada as
the simulation language (VAX Ada on a VAX 11/782).

   Our methodology includes making our representation as close
to that on the actual factory floor, and as a result we have
chosen to represent each STATION by a task. Our typical factory
floor may have upto 1000 stations.

   Thus we represent the STATION entity by a task type and at
run time the user enters the number of STATIONS. The stations
are then created dynamically (using access type pointers to the
STATION task type).

   The problem that we have is that we are unable to create a
large number of stations. After creating about 70 STATION tasks
we get "STORAGE ERROR". However, we seem to have sufficient
virtual memory allocated plus the paging tables etc. all seem
to be OK. 

   Thus my question relates to why I can't create as many stations
as I'd like to. I feel that the problem is related to the way
in which I have chosen to implement the STATION task type (please
see below) rather than an insufficient allocation of a memory
related parameter on the VAX.

Some relevant code sections are shown below.
Each station has an access type record that contains it's parameters.
These parameters are updated by calls on several re-entrant procedures.
----------------------------------------------------------------------------

task type STATION_TYPE is
   pragma PRIORITY(7);
   entry STATION_ADDRESS(I: in BUS_RANGE; J: in ADDRESS);
end STATION_TYPE;

for STATION_TYPE'STORAGE_SIZE use 60*512;
pragma TASK_STORAGE(STATION_TYPE,0);
type STATION_POINTER is access STATION_TYPE;
NEW_STATION: STATION_POINTER;


with MAC; -- package MAC contains re-entrant procedures
          -- MAC_MANAGEMENT, RXM, IFM, ACM

task body STATION_TYPE is			

STATION_PARAMETERS: A_TASK_DECLARATIONS; -- A_TASK_DECLARATIONS is an access 
                                         -- type pointer to a large record
                                         -- that contains about 50 variables
                                         -- that are unique to each station.

begin

   STATION_PARAMETERS := new TASK_DECLARATIONS;	-- instantiate station record

   accept STATION_ADDRESS(I: in BUS_RANGE; J: in ADDRESS) do  -- accept address
      STATION_PARAMETERS.BUS_CONNECTION := I;		      -- from main  
      STATION_PARAMETERS.TS := J;			      -- procedure
      STATION_PARAMETERS.PS := J;
      STATION_PARAMETERS.NS := J;
   end STATION_ADDRESS;

   MAC.MAC_MANAGEMENT(STATION_PARAMETERS.POWER_OK, 	      -- call on  
                      STATION_PARAMETERS.IN_RING_DESIRED);    -- re-entrant
                                                              -- procedure 
                                                              -- MAC_MANAGEMENT

   loop 

      MAC.RXM(STATION_PARAMETERS); -- call on re-entrant procedure RXM
      MAC.ACM(STATION_PARAMETERS); -- call on re-entrant procedure ACM
      MAC.IFM.PASS_DATA_FRAME(STATION_PARAMETERS); -- call on re-entrant 
                                                   -- procedure IFM
   end loop;

end STATION_TYPE;

----------------------------------------------------------------------------

   I'd appreciate any help I can get. Also any criticisms relating
to my methodology of using one task per station and using re-entrant 
calls for the common code.

   If there is sufficient interest, I will summarize any replies 
that I get (with appropriate credits) to the net.

   Thanks very much in advance.

   Asheem Chandna			CSNET : asheem@case.csnet
   Graduate Student 			ARPA  : asheem%case@csnet-relay.arpa
   Computer Engineering			USENET: decvax!cwruecmp!asheem
   Case Western Reserve University      (all mail is locally forwarded to
                                         asheem@cwcais)

p.s. If it is OK for me to call you, please include your phone number with
     your mail message. Thanks.

mdash@sfsup.UUCP (03/10/87)

In article <1859@cwruecmp.UUCP> asheem@cwruecmp.UUCP (Asheem Chandna) writes:
>
>Hi,
>
>   Thus we represent the STATION entity by a task type and at
>run time the user enters the number of STATIONS. The stations
>are then created dynamically (using access type pointers to the
>STATION task type).
>
>   The problem that we have is that we are unable to create a
>large number of stations. After creating about 70 STATION tasks
>we get "STORAGE ERROR". However, we seem to have sufficient
>virtual memory allocated plus the paging tables etc. all seem
>to be OK. 
>
>Each station has an access type record that contains it's parameters.
>These parameters are updated by calls on several re-entrant procedures.
>
>   I'd appreciate any help I can get. Also any criticisms relating
>to my methodology of using one task per station and using re-entrant 
>calls for the common code.

I can't see that re-entrant code has anything to do with this problem.
All Ada-generated code that does not reference persistent data should be
re-entrant.

According to the technical summary, VAX Ada allocates a sub-heap (access
collection) for each access type.  So the likely source of your problem is
that you are exhausting this pre-allocated space.  The obvious solution is
to allocate a larger access collection using a length clause for the access
type, i.e.,

	for A_TASK_DECLARATIONS'STORAGE_SIZE use ENOUGH_SPACE;

Of course, this will work only if VAX Ada implements length clauses for
access collections; I don't know offhand whether it does.  See LRM 13.2.

Mike Scheer
AT&T Information Systems, Summit NJ
201-522-6196