comp.lang.ada
 help / color / mirror / Atom feed
* How to terminate all running tasks?
@ 2020-06-10 11:14 Gilbert Gosseyn
  2020-06-10 12:12 ` Niklas Holsti
  2020-06-10 13:49 ` Jeffrey R. Carter
  0 siblings, 2 replies; 7+ messages in thread
From: Gilbert Gosseyn @ 2020-06-10 11:14 UTC (permalink / raw)


Hi,
-- package spezification
package packp6 is
   procedure tp6pm(N : Long_Integer);
end packp6;

-- package body
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Task_Identification;
package body packp6 is
   procedure tp6pm(N : Long_Integer) is
      use Ada.Task_Identification;
      package LIO is new Integer_IO(Long_Integer);
      solution_found : exception;

      task p6p;
      task p6m;

      task body p6p is
         pp,i : Long_Integer := 0;
      begin
         loop
            i := i+1;
            pp := 6*i+1;
            if N mod pp = 0 then
               new_line;put("pp= ");LIO.put(pp);
               raise solution_found;
            end if;
         end loop;
      end p6p;

      task body p6m is
         pm,i : Long_Integer := 0;
      begin
         loop
            i := i+1;
            pm := 6*i-1;
            if N mod pm = 0 then
               new_line;put("pm= ");LIO.put(pm);
               raise solution_found;
            end if;
         end loop;
      end p6m;
   begin
      null;
   exception
      when solution_found =>
         Abort_Task(p6p'Identity);
         Abort_Task(p6m'Identity);    
   end tp6pm;
end packp6;

-- test
with packp6; use packp6;
procedure P6_Test is
NN : Long_Integer := 11111111111111111;
begin
   tp6pm(NN);
end P6_Test;

-- test result:

pm=         2071723
pp=     5363222357


When in a task the exception solution_found is raised, then I want all running tasks to be terminated immediately. Apparently this does not happen. How to improve?

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

* Re: How to terminate all running tasks?
  2020-06-10 11:14 How to terminate all running tasks? Gilbert Gosseyn
@ 2020-06-10 12:12 ` Niklas Holsti
  2020-06-10 12:29   ` Niklas Holsti
  2020-06-10 13:49 ` Jeffrey R. Carter
  1 sibling, 1 reply; 7+ messages in thread
From: Niklas Holsti @ 2020-06-10 12:12 UTC (permalink / raw)


On 2020-06-10 14:14, Gilbert Gosseyn wrote:
> Hi,

It would be easier to understand your post if you started with the 
explanation and question, rather than throwing a bunch of uncommented 
code at the reader.

> -- package spezification
> package packp6 is
>     procedure tp6pm(N : Long_Integer);
> end packp6;
> 
> -- package body
> with Ada.Text_IO; use Ada.Text_IO;
> with Ada.Task_Identification;
> package body packp6 is
>     procedure tp6pm(N : Long_Integer) is
>        use Ada.Task_Identification;
>        package LIO is new Integer_IO(Long_Integer);
>        solution_found : exception;
> 
>        task p6p;
>        task p6m;
> 
>        task body p6p is
>           pp,i : Long_Integer := 0;
>        begin
>           loop
>              i := i+1;
>              pp := 6*i+1;
>              if N mod pp = 0 then
>                 new_line;put("pp= ");LIO.put(pp);
>                 raise solution_found;
>              end if;
>           end loop;


This is the last point at which you can handle the "raise" above. If 
there is no handler here, WITHIN task p6p, the exception will try to 
propagate out of the task, which will terminate the task and STOP the 
propagation of the exception.

>        end p6p;
> 
>        task body p6m is
>           pm,i : Long_Integer := 0;
>        begin
>           loop
>              i := i+1;
>              pm := 6*i-1;
>              if N mod pm = 0 then
>                 new_line;put("pm= ");LIO.put(pm);
>                 raise solution_found;
>              end if;
>           end loop;


Same comment as above.

>        end p6m;
>     begin
>        null;
>     exception
>        when solution_found =>


This handler is never entered, because the "null" statement above does 
not raise solution_found.

>           Abort_Task(p6p'Identity);
>           Abort_Task(p6m'Identity);
>     end tp6pm;
> end packp6;


    [snip]

> When in a task the exception solution_found is raised, then I want
> all running tasks to be terminated immediately.

It is not possible to use an exception, raised in a task, to signal 
something outside the task in that way.

> Apparently this does not happen. How to improve?


You must use some other way to inform the main subprogram that a 
solution has been found. There are may ways, but for example you can use 
an synchronization object as follows:

    with Ada.Synchronous_Task_Control;
    ...
    solution_found : Ada.Synchronous_Task_Control.Suspension_Object;
    ...
    task body p6p
       ...
       Ada.Synchronous_Task_Control.Set_True (solution_found);
       -- Instead of the "raise".
    ...
    same for task p6m

and in the main subprogram, instead of the null statement and the 
exception handler:

    Ada.Synchronous_Task_Control.Suspend_Until_True (solution_found);
    abort p6p;
    abort p6m;

-- 
Niklas Holsti

niklas holsti tidorum fi
       .      @       .

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

* Re: How to terminate all running tasks?
  2020-06-10 12:12 ` Niklas Holsti
@ 2020-06-10 12:29   ` Niklas Holsti
  2020-06-10 16:26     ` Simon Wright
  0 siblings, 1 reply; 7+ messages in thread
From: Niklas Holsti @ 2020-06-10 12:29 UTC (permalink / raw)


On 2020-06-10 15:12, Niklas Holsti wrote:

> and in the main subprogram, instead of the null statement and the 
> exception handler:
> 
>     Ada.Synchronous_Task_Control.Suspend_Until_True (solution_found);
>     abort p6p;
>     abort p6m;

Just an addendum: to make sure that the main subprogram runs, and is not 
starved by a child task that is still searching for a solution, you may 
want to make the priorities of the child tasks lower than the priority 
of the main subprogram (the environment task).

And a further note: generally one should avoid aborting tasks, as that 
easily leads to messy race conditions. Better to have the tasks 
terminate by themselves. For example, each of the search tasks could now 
and then call Ada.Synchronous_Task_Control.Current_State 
(solution_found) and terminate itself (exit the loop) if the result is True.

-- 
Niklas Holsti

niklas holsti tidorum fi
       .      @       .

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

* Re: How to terminate all running tasks?
  2020-06-10 11:14 How to terminate all running tasks? Gilbert Gosseyn
  2020-06-10 12:12 ` Niklas Holsti
@ 2020-06-10 13:49 ` Jeffrey R. Carter
  2020-06-10 14:45   ` Jeffrey R. Carter
  1 sibling, 1 reply; 7+ messages in thread
From: Jeffrey R. Carter @ 2020-06-10 13:49 UTC (permalink / raw)


On 6/10/20 1:14 PM, Gilbert Gosseyn wrote:
> package packp6 is
>    procedure tp6pm(N : Long_Integer);
> end packp6;
> 
> with Ada.Text_IO; use Ada.Text_IO;
> package body packp6 is
>    procedure tp6pm(N : Long_Integer) is
>       package LIO is new Integer_IO(Long_Integer);

         Solution_Found : Boolean := False;
         pragma Atomic (Solution_Found);
> 
>       task p6p;
> 
>       task body p6p is
>          pp,i : Long_Integer := 0;
>       begin
>          loop
               exit when Solution_Found;

>             i := i+1;
>             pp := 6*i+1;
>             if N mod pp = 0 then
>                new_line;put("pp= ");LIO.put(pp);
                  Solution_Found := True;
>             end if;
>          end loop;
>       end p6p;
>    begin
>       loop
            exit when Solution_Found;

>          i := i+1;
>          pm := 6*i-1;
>          if N mod pm = 0 then
>             new_line;put("pm= ");LIO.put(pm);
               Solution_Found := True;
>          end if;
>        end loop;
>    end tp6pm;
> end packp6;

-- 
Jeff Carter
"Unix and C are the ultimate computer viruses."
Richard Gabriel
99

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

* Re: How to terminate all running tasks?
  2020-06-10 13:49 ` Jeffrey R. Carter
@ 2020-06-10 14:45   ` Jeffrey R. Carter
  0 siblings, 0 replies; 7+ messages in thread
From: Jeffrey R. Carter @ 2020-06-10 14:45 UTC (permalink / raw)


On 6/10/20 3:49 PM, Jeffrey R. Carter wrote:
> On 6/10/20 1:14 PM, Gilbert Gosseyn wrote:
>> package packp6 is
>>    procedure tp6pm(N : Long_Integer);
>> end packp6;
>>
>> with Ada.Text_IO; use Ada.Text_IO;
>> package body packp6 is
>>    procedure tp6pm(N : Long_Integer) is
>>       package LIO is new Integer_IO(Long_Integer);
> 
>          Solution_Found : Boolean := False;
>          pragma Atomic (Solution_Found);
>>
>>       task p6p;
>>
>>       task body p6p is
>>          pp,i : Long_Integer := 0;
>>       begin
>>          loop
>                exit when Solution_Found;
> 
>>             i := i+1;
>>             pp := 6*i+1;
>>             if N mod pp = 0 then
>>                new_line;put("pp= ");LIO.put(pp);
>                   Solution_Found := True;
>>             end if;
>>          end loop;
>>       end p6p;

Sorry, of course the variables previously in P6m have to be declared here:

          pm,i : Long_Integer := 0;

>>    begin
>>       loop
>             exit when Solution_Found;
> 
>>          i := i+1;
>>          pm := 6*i-1;
>>          if N mod pm = 0 then
>>             new_line;put("pm= ");LIO.put(pm);
>                Solution_Found := True;
>>          end if;
>>        end loop;
>>    end tp6pm;
>> end packp6;

-- 
Jeff Carter
"Unix and C are the ultimate computer viruses."
Richard Gabriel
99

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

* Re: How to terminate all running tasks?
  2020-06-10 12:29   ` Niklas Holsti
@ 2020-06-10 16:26     ` Simon Wright
  2020-06-11  6:04       ` J-P. Rosen
  0 siblings, 1 reply; 7+ messages in thread
From: Simon Wright @ 2020-06-10 16:26 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> you may want to make the priorities of the child tasks lower than the
> priority of the main subprogram (the environment task).

which would normally be System.Default_Priority, unless you've said for
example

procedure Main_Program is
   pragma Priority (System.Default_Priority + 1);
is
...

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

* Re: How to terminate all running tasks?
  2020-06-10 16:26     ` Simon Wright
@ 2020-06-11  6:04       ` J-P. Rosen
  0 siblings, 0 replies; 7+ messages in thread
From: J-P. Rosen @ 2020-06-11  6:04 UTC (permalink / raw)


If you are really finished and just want to terminate the program, you
can also abort the main task.


-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

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

end of thread, other threads:[~2020-06-11  6:04 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-10 11:14 How to terminate all running tasks? Gilbert Gosseyn
2020-06-10 12:12 ` Niklas Holsti
2020-06-10 12:29   ` Niklas Holsti
2020-06-10 16:26     ` Simon Wright
2020-06-11  6:04       ` J-P. Rosen
2020-06-10 13:49 ` Jeffrey R. Carter
2020-06-10 14:45   ` Jeffrey R. Carter

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