comp.lang.ada
 help / color / mirror / Atom feed
From: cmarquis@blackslacks.nswc.navy.mil (Cheryl Marquis)
Subject: Re:  Activating tasks at Global Scope
Date: Mon, 15 Mar 1993 14:58:33 GMT
Date: 1993-03-15T14:58:33+00:00	[thread overview]
Message-ID: <1993Mar15.145833.18469@relay.nswc.navy.mil> (raw)

>The code below implements a producer-consumer system containing one
>producing task, two consuming tasks, and a bounded buffer task.  I am only
>interested in the tasking interactions, so I've omitted the actual buffer
>manipulations.  This code works fine under the Ada/ED compiler.  However, I
>would prefer to put the tasks at global scope rather than nest them inside
>the producer_consumer procedure.  I tried to do this by putting each task
>inside a package, but then I couldn't figure out how to activate the tasks
>when producer_consumer was invoked.  What I'd like is an architecture where
>the tasks are automatically started before or at the same time the the main
>subprogram is invoked.

>If I've done anything particularly gross, feel free to comment
>appropriately.  Nobody here knows Ada, so I put this together by copying
>fairly liberally from Ben-Ari's book, "Principles of Concurrent and
>Distributed Programming."

>Thanks,

>Scott

Scott as I see it you have two package options that will allow you a more
elegant start up without using delays.

They look basically alike the only difference is where the starting up of
the task is done.  Below is some code that I hope will help you.


with Text_IO;
use Text_IO;

package My_Task_Stuff is
  task Buffer is
--**** This entry provides a means of controlled task 
--     start ups.  Look at body to see how this works
    entry Start_Up;       
--****
    entry insert(item: in Integer);
    entry remove(item: out Integer);
--**** This entry provides a means of controlled task 
--     shut downs.  Look at body to see how this works
    entry Shut_Down;       
--****
  end Buffer;


  task Producer is
--**** This entry provides a means of controlled task 
--     start ups.  Look at body to see how this works
    entry Start_Up;       
--****
--**** This entry provides a means of controlled task 
--     shut downs.  Look at body to see how this works
    entry Shut_Down;       
--****


  task Consumer1;
--**** This entry provides a means of controlled task 
--     start ups.  Look at body to see how this works
    entry Start_Up;       
--****
--**** This entry provides a means of controlled task 
--     shut downs.  Look at body to see how this works
    entry Shut_Down;       
--****

  task Consumer2;
--**** This entry provides a means of controlled task 
--     start ups.  Look at body to see how this works
    entry Start_Up;       
--****
--**** This entry provides a means of controlled task 
--     shut downs.  Look at body to see how this works
    entry Shut_Down;       
--****


end My_Task_Stuff;


package body My_Task_Stuff is

  task body Buffer is
    count: Integer := 0;

    begin
--**** put Start up before loop.  Task will have to
--     wait here until the start up is called.

      accept Start_Up;
      -- any initializing can be done here also

      loop
        select when count < 10 =>
          accept insert(item: in Integer) do
            -- insert item into the buffer
            null;
          end insert;
          count := count + 1;

        or when count > 0 =>
          accept remove(item: out Integer) do
            -- remove an object from the buffer and assign it to item
            null;
          end remove;
          count := count - 1;
        or 

--**** This will give you controlled task exits.  You decide
--     when the task should end
          accept Shut_Down;
          exit;

        end select;

      end loop;
    end Buffer;

  task body Producer is
    n: integer;
    
    begin
--**** put Start up before loop.  Task will have to
--     wait here until the start up is called.

      accept Start_Up;
      -- any initializing can be done here also

      loop
--**** This will give you controlled task exits.  You decide
--     when the task should end
        select
           accept Shut_Down;
           exit;

        else
           -- give n an appropriate value
           Buffer.insert(n);

        end select;
      end loop;
  end Producer;

  task body Consumer1 is
    n: integer;
    
    begin
--**** put Start up before loop.  Task will have to
--     wait here until the start up is called.

      accept Start_Up;
      -- any initializing can be done here also

      loop

--**** This will give you controlled task exits.  You decide
--     when the task should end.
        select 
           accept Shut_Down;
           exit;

        else
           Buffer.remove(n);
           -- do something with n
        end select;
      end loop;
  end Consumer1;

  task body Consumer2 is
    n: integer;
    
    begin
--**** put Start up before loop.  Task will have to
--     wait here until the start up is called.

      accept Start_Up;
      -- any initializing can be done here also

      loop
--**** This will give you controlled task exits.  You decide
--     when the task should end
        select
           accept Shut_Down;
           exit;

        else
           Buffer.remove(n);
           -- do something with n
        end select;
      end loop;
  end Consumer2;

--**** Now here you have a choice.  You can either start these tasks
--     in the elaboration area of this package... 

begin -- My_Task_Stuff

  Producer.Start_Up;
  Consumer1.Start_Up;
  Consumer2.Start_Up;

end My_Task_Stuff;


with My_Task_Stuff;
procedure producer_consumer is

begin
  null;   -- will not terminate until all dependent
          -- tasks terminate
end producer_consumer;


--**** ... or call the Start_Ups from the main procedure
end My_Task_Stuff

with My_Task_Stuff;
procedure producer_consumer is

begin

   Producer.Start_Up;
   Consumer1.Start_Up;
   Consumer2.Start_Up;

end producer_consumer;

--**** One last thing; you can have procedure calls to your tasks
--     and hide the task inside the body instead of having a direct
--     task call specified in the Package Spec.



I hope I have helped and not confused you too badly.  If you have
any questions feel free to email me.


Cheryl R.S. Marquis
cmarquis@unode1.nswc.navy.mil

<no clever quote to put here...............YET!>




             reply	other threads:[~1993-03-15 14:58 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1993-03-15 14:58 Cheryl Marquis [this message]
  -- strict thread matches above, loose matches on Subject: below --
1993-03-10  3:32 Activating tasks at global scope Scott Meyers
1993-03-10 17:11 ` Robert I. Eachus
1993-03-11  3:56   ` Scott Meyers
1993-03-11 17:57     ` Dave Collard x7468
1993-03-11  2:51 ` Michael Feldman
replies disabled

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