comp.lang.ada
 help / color / mirror / Atom feed
* Ada tasking question.
@ 1996-10-18  0:00 whiting_ms@corning.com (Matt Whiting)
  0 siblings, 0 replies; 20+ messages in thread
From: whiting_ms@corning.com (Matt Whiting) @ 1996-10-18  0:00 UTC (permalink / raw)




I'm just learning Ada and am completely unfamiliar with any implementation
details of various Ada compilers/run-time environments.  I'm using ObjectAda
V7.0 under Windows NT 3.51.

My novice question is:  Is it possible to query a running system to determine
what Ada tasks are available on the system, what their current execution state
is, and what public methods each has?  Something akin to the TAS or ATL command
on RSX (I know I'm dating my skills here) or maybe the VMS SHOW SYSTEM command.
I've quickly reviewed the Rationale document and the ARM, but it is not
obvious if this is possible or how one might approach the problem.  There was a
reference to a Task Control Block, but it wasn't clear to me if that is a user
defined data structure or part of some "run time" component of Ada.

I'd like to write a Windows/Ada task that could be executed and then used to
"browse" a system to see what tasks are there.  Then I would like to be able to
"manually" issue commands (send messages, invoke methods, whatever the correct
OO terminology is!) to these tasks much as another task would do in a "real"
multitasking environment.  

Any suggestions or document references will be appreciated and no I'm not a
student!  Well, I'm a student in that I'm learning something new, but I'm not a
"formal" student trying to get help with a class assignment.

TIA,
Matt

-------------------------------------------------------------------------------
Matthew S. Whiting, P.E.         | Corning Incorporated | (607) 974-6317 phone
Manager Advanced Control Systems | HP-ME-01-034         | (607) 974-6752 fax
whiting_ms@corning.com           | Corning, NY 14831    |





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

* Ada tasking question
@ 2007-04-18 18:13 Stefan Bellon
  2007-04-18 18:40 ` Randy Brukardt
                   ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: Stefan Bellon @ 2007-04-18 18:13 UTC (permalink / raw)


Hi all!

Although I am quite familiar with Ada, tasking is quite new to me, so
please bear with me with my question. ;-)

I have a set of buckets where I do have to do some processing on them.
This processing can be done in parallel for each bucket. The results
of the processing however are accumulated into another data structure.

At present I have task types for the processing of the buckets, an
access type to the task type and basically just do:

   declare
      type Task_Access is access all Task_Type;
      My_Task : Task_Access;
   begin
      for I in Buckets'Range loop
         My_Task := new Task_Type'(Buckets (I));
      end loop;
   end;

The result data structure is a protected object with an entry Add that
adds the processing result to the container and which is called by the
task body.

All is well so far.

However the number of buckets may be quite large and I have the feeling
that the context switching which is needed for say 1000 or more tasks
eats up the gain of the parallelism. At least in my test cases I do not
gain anything at all on a Core Duo system.

Therefore I have the idea of just starting N tasks in parallel (where N
can be specified by the user e.g. according to the number of CPU cores
of the machine) instead of tasks for all buckets at once.

Starting N tasks, then waiting for them to get all finished and only
then starting the next N tasks is not difficult. But how would I do it,
so that there are always N tasks running (apart of course when
everything has been processed) and that a new tasks is starting on the
next bucket as soon as a task on a previous bucket has finished?

Any ideas are very welcome!

-- 
Stefan Bellon



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

* Re: Ada tasking question
  2007-04-18 18:13 Ada tasking question Stefan Bellon
@ 2007-04-18 18:40 ` Randy Brukardt
  2007-04-18 20:12   ` Jeffrey R. Carter
  2007-04-18 21:08   ` Leif Holmgren
  2007-04-18 19:50 ` Alex R. Mosteo
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 20+ messages in thread
From: Randy Brukardt @ 2007-04-18 18:40 UTC (permalink / raw)


"Stefan Bellon" <sbellon@sbellon.de> wrote in message
news:20070418201307.18a85fd9@cube.tz.axivion.com...
...
> Therefore I have the idea of just starting N tasks in parallel (where N
> can be specified by the user e.g. according to the number of CPU cores
> of the machine) instead of tasks for all buckets at once.
>
> Starting N tasks, then waiting for them to get all finished and only
> then starting the next N tasks is not difficult. But how would I do it,
> so that there are always N tasks running (apart of course when
> everything has been processed) and that a new tasks is starting on the
> next bucket as soon as a task on a previous bucket has finished?
>
> Any ideas are very welcome!

I'd suggest organizing the tasks as workers and the buckets as jobs. The
idea is that each task is a loop that just gets a job (a bucket in your
case), processes it, sends the result, and gets another job, etc. You just
need a protected data structure to serve the jobs, and an array of worker
tasks, and then you can easy vary N to any value you want to try.

                          Randy.





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

* Re: Ada tasking question
  2007-04-18 18:13 Ada tasking question Stefan Bellon
  2007-04-18 18:40 ` Randy Brukardt
@ 2007-04-18 19:50 ` Alex R. Mosteo
  2007-04-18 23:00   ` Stefan Bellon
  2007-04-19 20:37   ` Pascal Obry
  2007-04-19  2:13 ` jimmaureenrogers
  2007-04-19  7:49 ` Dmitry A. Kazakov
  3 siblings, 2 replies; 20+ messages in thread
From: Alex R. Mosteo @ 2007-04-18 19:50 UTC (permalink / raw)


Stefan Bellon wrote:

> Hi all!
> 
> Although I am quite familiar with Ada, tasking is quite new to me, so
> please bear with me with my question. ;-)
> 
> I have a set of buckets where I do have to do some processing on them.
> This processing can be done in parallel for each bucket. The results
> of the processing however are accumulated into another data structure.
> 
> At present I have task types for the processing of the buckets, an
> access type to the task type and basically just do:
> 
>    declare
>       type Task_Access is access all Task_Type;
>       My_Task : Task_Access;
>    begin
>       for I in Buckets'Range loop
>          My_Task := new Task_Type'(Buckets (I));

Be aware that this causes heap consumption. That is, a finished task doesn't
just vanishes, it has some heap used for task context that is not
automatically released. To properly free a task access you must ensure that
the task is terminated (My_Task'Terminated) before doing an
Unchecked_Deallocation.

If you try to free an unfinished task, the call won't fail but the task
context memory won't be freed...

I have only GNAT experience though.

>       end loop;
>    end;
> 
> The result data structure is a protected object with an entry Add that
> adds the processing result to the container and which is called by the
> task body.
> 
> All is well so far.
> 
> However the number of buckets may be quite large and I have the feeling
> that the context switching which is needed for say 1000 or more tasks
> eats up the gain of the parallelism. At least in my test cases I do not
> gain anything at all on a Core Duo system.
> 
> Therefore I have the idea of just starting N tasks in parallel (where N
> can be specified by the user e.g. according to the number of CPU cores
> of the machine) instead of tasks for all buckets at once.
> 
> Starting N tasks, then waiting for them to get all finished and only
> then starting the next N tasks is not difficult. But how would I do it,
> so that there are always N tasks running (apart of course when
> everything has been processed) and that a new tasks is starting on the
> next bucket as soon as a task on a previous bucket has finished?
> 
> Any ideas are very welcome!
> 




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

* Re: Ada tasking question
  2007-04-18 18:40 ` Randy Brukardt
@ 2007-04-18 20:12   ` Jeffrey R. Carter
  2007-04-18 22:43     ` Stefan Bellon
  2007-04-18 21:08   ` Leif Holmgren
  1 sibling, 1 reply; 20+ messages in thread
From: Jeffrey R. Carter @ 2007-04-18 20:12 UTC (permalink / raw)


Randy Brukardt wrote:
> 
> I'd suggest organizing the tasks as workers and the buckets as jobs. The
> idea is that each task is a loop that just gets a job (a bucket in your
> case), processes it, sends the result, and gets another job, etc. You just
> need a protected data structure to serve the jobs, and an array of worker
> tasks, and then you can easy vary N to any value you want to try.

In this case, I'd say all that's needed is a protected object to supply 
the index into the Buckets array of the next bucket needing processing.

-- 
Jeff Carter
"Blessed is just about anyone with a vested interest in the status quo."
Monty Python's Life of Brian
73



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

* Re: Ada tasking question
  2007-04-18 18:40 ` Randy Brukardt
  2007-04-18 20:12   ` Jeffrey R. Carter
@ 2007-04-18 21:08   ` Leif Holmgren
  2007-04-18 22:57     ` Stefan Bellon
  1 sibling, 1 reply; 20+ messages in thread
From: Leif Holmgren @ 2007-04-18 21:08 UTC (permalink / raw)



Randy Brukardt wrote:
> "Stefan Bellon" <sbellon@sbellon.de> wrote in message
>>
>>Starting N tasks, then waiting for them to get all finished and only
>>then starting the next N tasks is not difficult.
...

> and an array of worker
> tasks, and then you can easy vary N to any value you want to try.

If my memory does not fail me the advice to use an array here is double 
good.

First of all you don't need to bother with the nitty gritty details of 
dynamic allocation yourself.

Secondly and perhaps most important Ada will handle the synchronization 
of task termination for you automatically. It will not allow the array 
to go out of scope before all the tasks are completed.

Years ago I implemented such a system (using dynamically allocated 
tasks) and it worked very well. By doing as suggested you will gain 
maximum performance even if the buckets take different time to process.

/Leif




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

* Re: Ada tasking question
  2007-04-18 20:12   ` Jeffrey R. Carter
@ 2007-04-18 22:43     ` Stefan Bellon
  2007-04-19  2:02       ` Steve
  0 siblings, 1 reply; 20+ messages in thread
From: Stefan Bellon @ 2007-04-18 22:43 UTC (permalink / raw)


Jeffrey R. Carter wrote:

> Randy Brukardt wrote:
> > 
> > I'd suggest organizing the tasks as workers and the buckets as
> > jobs. The idea is that each task is a loop that just gets a job (a
> > bucket in your case), processes it, sends the result, and gets
> > another job, etc. You just need a protected data structure to serve
> > the jobs, and an array of worker tasks, and then you can easy vary
> > N to any value you want to try.

Thanks for this excellent idea! I have implemented that now.

> In this case, I'd say all that's needed is a protected object to
> supply the index into the Buckets array of the next bucket needing
> processing.

Yes, in fact I already implemented it this way before I saw your
posting. :-)

   protected Bucket_Jobs is
      procedure Init (Index : in Integer);
      entry Next (Index : out Integer);
   private
      Current : Integer;
   end Bucket_Jobs;

   protected body Bucket_Jobs is
      procedure Init (Index : in Integer) is
      begin
         Current := Index;
      end Init;

      entry Next (Index : out Integer) when True is
      begin
         Index := Current;
         Current := Current + 1;
      end Next;
   end Bucket_Jobs;

Initialization is done with Bucket_Jobs.Init (Buckets'First) and the
tasks themselves check for Current in Buckets'Range.

It kind of works, but I experience some other strange effect (see my
reply to Leif Holmgren).

-- 
Stefan Bellon



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

* Re: Ada tasking question
  2007-04-18 21:08   ` Leif Holmgren
@ 2007-04-18 22:57     ` Stefan Bellon
  2007-04-18 23:41       ` Brian May
                         ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Stefan Bellon @ 2007-04-18 22:57 UTC (permalink / raw)


Leif Holmgren wrote:

> If my memory does not fail me the advice to use an array here is
> double good.
> 
> First of all you don't need to bother with the nitty gritty details
> of dynamic allocation yourself.
> 
> Secondly and perhaps most important Ada will handle the
> synchronization of task termination for you automatically. It will
> not allow the array to go out of scope before all the tasks are
> completed.

Yes, I realized this after I read Randy's posting. This idea is just
excellent.

> Years ago I implemented such a system (using dynamically allocated 
> tasks) and it worked very well. By doing as suggested you will gain 
> maximum performance even if the buckets take different time to
> process.

Well, here I seem to have still problems. "In the beginning", it seems
to work very well. Debug output shows that the tasks do work and fetch
new jobs and so on. But as time goes by, some tasks get "lazy" and I
have no idea why. They do not terminate, but do not fetch new jobs
although there are still open buckets to process.

The task body looks (very shortened) like this:

   type Buckets_Array is array (Natural range <>) of Bucket_Item;

   type Buckets_Access is access all Buckets_Array;

   task type Bucket_Worker (Buckets : Buckets_Access) is
      entry Set_Task_No (No : in Integer);  --  Just for debugging
   end Bucket_Worker;

   task body Bucket_Worker
   is
      Task_No         : Integer;
      Current         : Integer;
   begin
      accept Set_Task_No (No : in Integer) do
         Task_No := No;
      end Set_Task_No;
      Debug ("Task" & Task_No'Img & ": starting");
      Bucket_Jobs.Next (Current);
      while Current in Buckets.all'Range loop
         Debug ("Task" & Task_No'Img & ": bucket" & Current'Img)
         --  Do the work.
         Bucket_Jobs.Next (Current);
      end loop;
      Debug ("Task" & Task_No'Img & ": finished");
   end Bucket_Worker;

The initialization and starting of the tasks looks like this:

      Bucket_Jobs.Init (My_Buckets'First);
      declare
         Compare_Tasks : array (1 .. Num_CPUs) of Bucket_Worker
           (Buckets  => My_Buckets'Unrestricted_Access);
      begin
         for I in Compare_Tasks'Range loop
            Compare_Tasks (I).Set_Task_No (I);
         end loop;
      end;

And Bucket_Jobs is the protected object as posted in the followup to
Jeffrey Carter.

The observation of the tasks that get lazy over the time can be made by
two ways: First, the debug output shows a lot of activity for _all_
four tasks in the beginning, but at the end, only one task fetches new
jobs although the others have not finished and there are buckets left
to process. The second way of observing is by looking at the processor
usage with something like top. In the beginning it is quite over 100 %
and all CPUs are used. Later one it drops and only one CPU is used.

I have no explanation for this behaviour, but perhaps you can spot
something which is fundamentally wrong in my code?

-- 
Stefan Bellon



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

* Re: Ada tasking question
  2007-04-18 19:50 ` Alex R. Mosteo
@ 2007-04-18 23:00   ` Stefan Bellon
  2007-04-19 20:37   ` Pascal Obry
  1 sibling, 0 replies; 20+ messages in thread
From: Stefan Bellon @ 2007-04-18 23:00 UTC (permalink / raw)


Alex R. Mosteo wrote:

> Be aware that this causes heap consumption. That is, a finished task
> doesn't just vanishes, it has some heap used for task context that is
> not automatically released. To properly free a task access you must
> ensure that the task is terminated (My_Task'Terminated) before doing
> an Unchecked_Deallocation.
> 
> If you try to free an unfinished task, the call won't fail but the
> task context memory won't be freed...

Yes, thanks for that hint. It was just prototype code as I wanted to
get the other issue solved first. I still had task deallocation on my
"todo" list. ;-)

-- 
Stefan Bellon



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

* Re: Ada tasking question
  2007-04-18 22:57     ` Stefan Bellon
@ 2007-04-18 23:41       ` Brian May
  2007-04-19  0:25       ` Randy Brukardt
  2007-04-19  0:50       ` Jeffrey R. Carter
  2 siblings, 0 replies; 20+ messages in thread
From: Brian May @ 2007-04-18 23:41 UTC (permalink / raw)


>>>>> "Stefan" == Stefan Bellon <sbellon@sbellon.de> writes:

    Stefan> Well, here I seem to have still problems. "In the
    Stefan> beginning", it seems to work very well. Debug output shows
    Stefan> that the tasks do work and fetch new jobs and so on. But
    Stefan> as time goes by, some tasks get "lazy" and I have no idea
    Stefan> why. They do not terminate, but do not fetch new jobs
    Stefan> although there are still open buckets to process.

At a quick guess, this sounds to me like an threading library, OS or
compiler specific issue.

What OS and version are you using? If Linux what kernel version? What
compiler are you using?

Also, I don't know how your Debug routine is implemented, is it
possible the Debug routine is somehow causing problems? Maybe some
sort locking or deadlock condition?
-- 
Brian May <bam@snoopy.apana.org.au>



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

* Re: Ada tasking question
  2007-04-18 22:57     ` Stefan Bellon
  2007-04-18 23:41       ` Brian May
@ 2007-04-19  0:25       ` Randy Brukardt
  2007-04-19  8:02         ` Stefan Bellon
  2007-04-19 12:47         ` Jacob Sparre Andersen
  2007-04-19  0:50       ` Jeffrey R. Carter
  2 siblings, 2 replies; 20+ messages in thread
From: Randy Brukardt @ 2007-04-19  0:25 UTC (permalink / raw)


"Stefan Bellon" <sbellon@sbellon.de> wrote in message
news:20070419005738.692eeeb6@cube.tz.axivion.com...
...
> Well, here I seem to have still problems. "In the beginning", it seems
> to work very well. Debug output shows that the tasks do work and fetch
> new jobs and so on. But as time goes by, some tasks get "lazy" and I
> have no idea why. They do not terminate, but do not fetch new jobs
> although there are still open buckets to process.

My instant guess is that an exception was raised and not handled in the
task. That will make it "disappear" and it would stop working. But it
doesn't terminate until all of the tasks in the set finish, Your tasks
should have an "others" exception handler at the outmost level with a Debug
call to ensure that they didn't fail for some reason.

I use something like:

     exception
          when Oops:others =>
                 Debug ("Worker Task Failed: exception raised: " &
                    Ada.Exceptions.Exception_Information (Oops));
    end Bucket_Worker;

(How useful this is depends on the information available in
Exception_Information [which is compiler-specific], but it should at least
be enough to find out what's happening, or to rule out this possibility).





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

* Re: Ada tasking question
  2007-04-18 22:57     ` Stefan Bellon
  2007-04-18 23:41       ` Brian May
  2007-04-19  0:25       ` Randy Brukardt
@ 2007-04-19  0:50       ` Jeffrey R. Carter
  2 siblings, 0 replies; 20+ messages in thread
From: Jeffrey R. Carter @ 2007-04-19  0:50 UTC (permalink / raw)


Stefan Bellon wrote:
> 
> Well, here I seem to have still problems. "In the beginning", it seems
> to work very well. Debug output shows that the tasks do work and fetch
> new jobs and so on. But as time goes by, some tasks get "lazy" and I
> have no idea why. They do not terminate, but do not fetch new jobs
> although there are still open buckets to process.

You can implement this without access types or values, and it would 
probably be a good exercise for you to figure out how to do so.

I agree with Brukardt that your problem is probably an unreported 
exception in the task. When tasks die, they do so silently, unless you 
have arranged for them to be noisy.

-- 
Jeff Carter
"Blessed is just about anyone with a vested interest in the status quo."
Monty Python's Life of Brian
73



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

* Re: Ada tasking question
  2007-04-18 22:43     ` Stefan Bellon
@ 2007-04-19  2:02       ` Steve
  0 siblings, 0 replies; 20+ messages in thread
From: Steve @ 2007-04-19  2:02 UTC (permalink / raw)


"Stefan Bellon" <sbellon@sbellon.de> wrote in message 
news:20070419004345.171ee93e@cube.tz.axivion.com...
> Jeffrey R. Carter wrote:
>
[snip]
> Yes, in fact I already implemented it this way before I saw your
> posting. :-)
>
>   protected Bucket_Jobs is
>      procedure Init (Index : in Integer);
>      entry Next (Index : out Integer);
>   private
>      Current : Integer;
>   end Bucket_Jobs;
>
>   protected body Bucket_Jobs is
>      procedure Init (Index : in Integer) is
>      begin
>         Current := Index;
>      end Init;
>
>      entry Next (Index : out Integer) when True is
>      begin
>         Index := Current;
>         Current := Current + 1;
>      end Next;
>   end Bucket_Jobs;
>

If you don't mind sacraficing portability, some systems have an "Interlocked 
Increment" function that is a very lightweight option for implementing this 
functionality.  On x86 architecture it basically maps to a hardware 
instruction that locks the bus while incrementing and returns the result.

Regards,
Steve
(The Duck)

>
> -- 
> Stefan Bellon 





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

* Re: Ada tasking question
  2007-04-18 18:13 Ada tasking question Stefan Bellon
  2007-04-18 18:40 ` Randy Brukardt
  2007-04-18 19:50 ` Alex R. Mosteo
@ 2007-04-19  2:13 ` jimmaureenrogers
  2007-04-19  7:49 ` Dmitry A. Kazakov
  3 siblings, 0 replies; 20+ messages in thread
From: jimmaureenrogers @ 2007-04-19  2:13 UTC (permalink / raw)


It is not efficient to create and destroy a number of tasks
to do this job. It is more efficient to create a static set of
tasks and let them cycle through the work as in the
following example:

with Ada.Text_Io; use Ada.Text_Io;

procedure Task_Test_01 is
   subtype Return_Value is Natural range 0..100;
   subtype Index is Return_Value range 1..Return_Value'Last;
   protected Indexer is
      procedure Get_Index(Next_Index : out Return_Value);
   private
      Current_Index : Return_Value := Return_Value'Last;
   end Indexer;

   protected body Indexer is
      procedure Get_Index(Next_Index : out Return_Value) is
      begin
         Next_Index := Current_Index;
         if Next_Index > Return_Value'First then
            Current_Index := Current_Index - 1;
         end if;
      end Get_Index;
   end Indexer;

   type Buckets is array(Index) of Integer;
   The_Buckets : Buckets := (Others => 0);

   task type Worker is
      entry Set_Id(Id : Positive);
   end Worker;

   task body Worker is
      My_Index : Return_Value;
      Working_Value : Integer;
      Id_Num : Positive;
   begin
      accept Set_Id(Id : Positive) do
         Id_Num := Id;
      end Set_Id;

      loop
         Indexer.Get_Index(My_Index);
         exit when My_Index = Return_Value'First;
         Working_Value := 2 * My_Index;
         Put_Line("Worker" & Positive'Image(Id_Num) & " at work.");
         The_Buckets(My_Index) := Working_Value;
      end loop;
   end Worker;
   Team : array(1..5) of Worker;
begin
   for I in Team'range loop
      Team(I).Set_Id(I);
   end loop;
end Task_Test_01;

Jim Rogers




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

* Re: Ada tasking question
  2007-04-18 18:13 Ada tasking question Stefan Bellon
                   ` (2 preceding siblings ...)
  2007-04-19  2:13 ` jimmaureenrogers
@ 2007-04-19  7:49 ` Dmitry A. Kazakov
  3 siblings, 0 replies; 20+ messages in thread
From: Dmitry A. Kazakov @ 2007-04-19  7:49 UTC (permalink / raw)


It makes no sense to finish a task after a bucket was processed. I would
propose an alternative design, where a task would ask the buckets
collection for a job to do. It would then process the bucket and ask for a
next one. When the collection responds: no more buckets, the task finishes:

type Bucket is new Ada.Finalization.[Limited_]Controlled ...
procedure Process (Job : in out Bucket);

type Bucket_List is record
   Buckets : Bucket_Array (...);
   Indexer : a protected object to index buckets concurrently
end record;

procedure Do_One (List : in out Bucket_List) is
begin
   Process (List.Buckets (List.Indexer.Get_Next));
      -- Get_Next raises exception No_Buckets,
      -- when the end of List.Buckets is reached
end Do_One;

task body Bucket_Worker is
begin
   loop
      Do_One (List);
   end loop;
exception
   when No_Buckets =>
      null;
end Bucket_Worker;

You start as many Bucket_Workers as you find appropriate.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



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

* Re: Ada tasking question
  2007-04-19  0:25       ` Randy Brukardt
@ 2007-04-19  8:02         ` Stefan Bellon
  2007-04-19 12:47         ` Jacob Sparre Andersen
  1 sibling, 0 replies; 20+ messages in thread
From: Stefan Bellon @ 2007-04-19  8:02 UTC (permalink / raw)


Randy Brukardt wrote:

> My instant guess is that an exception was raised and not handled in
> the task. That will make it "disappear" and it would stop working.

Ah, thanks, that's it. Everything is fine now. Thanks to all for your
help.

-- 
Stefan Bellon



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

* Re: Ada tasking question
  2007-04-19  0:25       ` Randy Brukardt
  2007-04-19  8:02         ` Stefan Bellon
@ 2007-04-19 12:47         ` Jacob Sparre Andersen
  2007-04-19 16:11           ` Anh Vo
  2007-04-20  4:32           ` Jeffrey R. Carter
  1 sibling, 2 replies; 20+ messages in thread
From: Jacob Sparre Andersen @ 2007-04-19 12:47 UTC (permalink / raw)


Randy Brukardt wrote:

> I use something like:
>
>      exception
>           when Oops:others =>
>                  Debug ("Worker Task Failed: exception raised: " &
>                     Ada.Exceptions.Exception_Information (Oops));
>     end Bucket_Worker;

The exception handler allows us to notice when one of the tasks dies.
But can we (re)start it somehow?  Or will we have to put an exception
handler inside the processing loop, and that way keep the task
running?

Jacob
-- 
"Then, after a second or so, nothing continued to happen."



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

* Re: Ada tasking question
  2007-04-19 12:47         ` Jacob Sparre Andersen
@ 2007-04-19 16:11           ` Anh Vo
  2007-04-20  4:32           ` Jeffrey R. Carter
  1 sibling, 0 replies; 20+ messages in thread
From: Anh Vo @ 2007-04-19 16:11 UTC (permalink / raw)


On Apr 19, 5:47 am, Jacob Sparre Andersen <spa...@nbi.dk> wrote:
> Randy Brukardt wrote:
> > I use something like:
>
> >      exception
> >           when Oops:others =>
> >                  Debug ("Worker Task Failed: exception raised: " &
> >                     Ada.Exceptions.Exception_Information (Oops));
> >     end Bucket_Worker;
>
> The exception handler allows us to notice when one of the tasks dies.
> But can we (re)start it somehow?  Or will we have to put an exception
> handler inside the processing loop, and that way keep the task
> running?

I always put exception handler inside the live_for_ever_task loop.
Only in a very rare case that it is very critical to terminate the
task. I will print out (log) lots of useful information before saying
Later Alligator.

AV





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

* Re: Ada tasking question
  2007-04-18 19:50 ` Alex R. Mosteo
  2007-04-18 23:00   ` Stefan Bellon
@ 2007-04-19 20:37   ` Pascal Obry
  1 sibling, 0 replies; 20+ messages in thread
From: Pascal Obry @ 2007-04-19 20:37 UTC (permalink / raw)
  To: Alex R. Mosteo

Alex R. Mosteo a �crit :

> If you try to free an unfinished task, the call won't fail but the task
> context memory won't be freed...

Just loop waiting for the task to terminate before calling free.

   while not T'Terminated loop
      delay 1.0;
   end loop;

   Free (T);

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



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

* Re: Ada tasking question
  2007-04-19 12:47         ` Jacob Sparre Andersen
  2007-04-19 16:11           ` Anh Vo
@ 2007-04-20  4:32           ` Jeffrey R. Carter
  1 sibling, 0 replies; 20+ messages in thread
From: Jeffrey R. Carter @ 2007-04-20  4:32 UTC (permalink / raw)


Jacob Sparre Andersen wrote:
> 
> The exception handler allows us to notice when one of the tasks dies.
> But can we (re)start it somehow?  Or will we have to put an exception
> handler inside the processing loop, and that way keep the task
> running?

Ada's exception-handling syntax does not directly provide for restarting 
or repeating the code that raised the exception. However, Ada does 
provide the building blocks to achieve that: You put a block statement 
with an exception handler inside a loop.

-- 
Jeff Carter
"C++ is like giving an AK-47 to a monk, shooting him
full of crack and letting him loose in a mall and
expecting him to balance your checking account
'when he has the time.'"
Drew Olbrich
52



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

end of thread, other threads:[~2007-04-20  4:32 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-04-18 18:13 Ada tasking question Stefan Bellon
2007-04-18 18:40 ` Randy Brukardt
2007-04-18 20:12   ` Jeffrey R. Carter
2007-04-18 22:43     ` Stefan Bellon
2007-04-19  2:02       ` Steve
2007-04-18 21:08   ` Leif Holmgren
2007-04-18 22:57     ` Stefan Bellon
2007-04-18 23:41       ` Brian May
2007-04-19  0:25       ` Randy Brukardt
2007-04-19  8:02         ` Stefan Bellon
2007-04-19 12:47         ` Jacob Sparre Andersen
2007-04-19 16:11           ` Anh Vo
2007-04-20  4:32           ` Jeffrey R. Carter
2007-04-19  0:50       ` Jeffrey R. Carter
2007-04-18 19:50 ` Alex R. Mosteo
2007-04-18 23:00   ` Stefan Bellon
2007-04-19 20:37   ` Pascal Obry
2007-04-19  2:13 ` jimmaureenrogers
2007-04-19  7:49 ` Dmitry A. Kazakov
  -- strict thread matches above, loose matches on Subject: below --
1996-10-18  0:00 whiting_ms@corning.com (Matt Whiting)

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