comp.lang.ada
 help / color / mirror / Atom feed
* Structure of the multitasking server
@ 2008-09-19 12:21 Maciej Sobczak
  2008-09-19 13:34 ` Jean-Pierre Rosen
  2008-09-19 23:01 ` anon
  0 siblings, 2 replies; 32+ messages in thread
From: Maciej Sobczak @ 2008-09-19 12:21 UTC (permalink / raw)


Hi all,

Imagine a server with fixed number of worker tasks. There is no queue
of jobs and jobs are immediately passed to one of the tasks that is
currently idle. There is a separate task (or just the main one) that
provides jobs for worker tasks.

I am concerned with the proper structure of objects - I mean in the
sense of recommended Ada practice.
Obviously there is a need for some shared resource where the
requesting task will put the job and from where the worker task will
pick it up.

This is more or less what I came up with, where the "channel" is a
single processing pipeline:

   type Worker_State is (Idle, Ready, Working);

   protected type Channel_State is
      procedure Post (J : in Job_Type);
      entry Get_Job (J : out Job_Type);
      function Busy return Boolean;
   private
      State : Worker_State := Idle;
      Job_To_Do : Job_Type;
   end Channel_State;

   protected body Channel_State is

      procedure Post (J : in Job_Type) is
      begin
         if State /= Idle then
            raise Program_Error;
         end if;

         Job_To_Do := J;
         State := Ready;
      end Post;

      entry Get_Job (J : out Job_Type) when State = Ready is
      begin
         J := Job_To_Do;
         State := Working;
      end Get_Job;

      function Busy return Boolean is
      begin
         return State /= Idle;
      end Busy;

   end Channel_State;

   type Channel;
   task type Worker_Task (Ch : access Channel);

   type Channel is record
      State : Channel_State;
      Worker : Worker_Task (Channel'Access);
   end record;

   task body Worker_Task is
      Job : Job_Type;
   begin
      loop
         Ch.all.Get_Job (Job);

         --  do the job ...

      end loop;
   end Worker_Task;

   Max_Channels : constant := 5;

   Channels : array (1 .. Max_Channels) of Channel;

My question is whether this is what a seasoned Ada programmer would
do.
Initially I tried to have two separate arrays, one for jobs and one
for worker tasks, but I found it difficult to link workers with their
respective jobs. After bundling them together in a single record that
is referenced from the task it worked and I actually find it
structured better.

The main task after constructing a job object finds some channel where
the worker task is not busy and posts the job to its shared state
component:

   loop
      Job := ...

      Found_Worker := False;
      for I in Channels'Range loop
         if not Channels (I).State.Busy then
            Channels (I).State.Post (Job);
            Found_Worker := True;
            exit;
         end if;
      end loop;

      if not Found_Worker then
         --  all pipelines are busy,
         --  but the overflow handling is not shown...
      end if;
   end loop;

All this works fine, but my question considers the choice of language
constructs and idioms.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



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

end of thread, other threads:[~2015-03-15 16:04 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-19 12:21 Structure of the multitasking server Maciej Sobczak
2008-09-19 13:34 ` Jean-Pierre Rosen
2008-09-19 17:02   ` Dmitry A. Kazakov
2008-09-21 17:30     ` Maciej Sobczak
2008-09-21 19:24       ` Dmitry A. Kazakov
2008-09-21 21:27         ` Maciej Sobczak
2008-09-22  8:12           ` Dmitry A. Kazakov
2008-09-22 12:47             ` Maciej Sobczak
2008-09-22 14:11               ` Dmitry A. Kazakov
2008-09-23  8:07                 ` Maciej Sobczak
2008-09-23  9:37                   ` Dmitry A. Kazakov
2008-09-23 10:47                   ` Jean-Pierre Rosen
2008-09-21 17:23   ` Maciej Sobczak
2008-09-22  8:23     ` Jean-Pierre Rosen
2015-03-12 16:07   ` gautier_niouzes
2015-03-12 21:38     ` Jacob Sparre Andersen
2015-03-12 22:39       ` gautier_niouzes
2015-03-13  8:15         ` Dmitry A. Kazakov
2015-03-13 20:16           ` gautier_niouzes
2015-03-13 20:47             ` Dmitry A. Kazakov
2015-03-15  7:43               ` gautier_niouzes
2015-03-15  8:35                 ` Simon Wright
2015-03-15  8:52                 ` J-P. Rosen
2015-03-15  9:21                   ` Jacob Sparre Andersen
2015-03-15 16:04                     ` Brad Moore
2015-03-13 23:04             ` Randy Brukardt
2015-03-14  8:22               ` Simon Wright
2008-09-19 23:01 ` anon
2008-09-21 17:37   ` Maciej Sobczak
2008-09-22  2:32     ` anon
2008-09-22 13:05       ` Maciej Sobczak
2008-09-23  9:25         ` anon

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