* 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 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 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
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