comp.lang.ada
 help / color / mirror / Atom feed
* ATC, an  example please.
@ 2005-06-30  8:44 e.coli
  2005-06-30  9:32 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: e.coli @ 2005-06-30  8:44 UTC (permalink / raw)


how ATC work?
can you fix this example,please?

------------------------------------------------------------------
with Ada.Text_Io;

procedure Atc_Test is

   task A_Task is
      entry Foo;
   end A_Task;

   task body A_Task is
   begin
      loop
         accept Foo;
         Ada.Text_Io.Put_Line("one.start");
         for Iteration in 1..100000 loop
            Ada.Text_Io.Put(".");
         end loop;
         Ada.Text_Io.Put_Line("one.end");
      end loop;
   end A_Task;

begin
   select
      delay 2.0;
      Ada.Text_Io.Put_Line ("Long calculation abandoned");
   then
      abort
      A_Task.Foo;
   end select;
   Ada.Text_Io.Put_Line ("end main");

end Atc_Test;
-----------------------------------------------------------------

best regards
Maurizio




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

* Re: ATC, an  example please.
  2005-06-30  8:44 ATC, an example please e.coli
@ 2005-06-30  9:32 ` Dmitry A. Kazakov
  2005-06-30  9:59   ` e.coli
                     ` (2 more replies)
  2005-06-30  9:32 ` e.coli
  2005-07-02  8:18 ` Craig Carey
  2 siblings, 3 replies; 9+ messages in thread
From: Dmitry A. Kazakov @ 2005-06-30  9:32 UTC (permalink / raw)


On 30 Jun 2005 01:44:52 -0700, e.coli wrote:

> how ATC work?

ATC transfers control, it does not abort any other task. This is why you
have to explicitly kill the task. Another error in your code is that you
wait not for the calculation completion, but for its initiation.

> can you fix this example,please?

Try this:

with Ada.Text_Io;

procedure Atc_Test is
   task A_Task is
      entry Start;
      entry Ready;
   end A_Task;

   task body A_Task is
   begin
      loop
         accept Start;
         Ada.Text_Io.Put_Line("one.start");
         for Iteration in 1..100_0000 loop
            Ada.Text_Io.Put (".");
         end loop;
         accept Ready;
         Ada.Text_Io.Put_Line("one.end");
      end loop;
   end A_Task;

begin
   A_Task.Start;      -- Initiate calculation
   select
      delay 2.0;      -- After time-out expiration,
      abort A_Task;   -- kill the task!
      Ada.Text_Io.Put_Line ("Long calculation abandoned");
   then
      abort A_Task.Ready;   -- Wait for completion
   end select;
   Ada.Text_Io.Put_Line ("end main");

end Atc_Test;

----------------------
N.B. This is a wrong way to do things. Don't use ATC if you cannot prove
that there is no other way. Don't abort task, which is even more brutal
than ATC.

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



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

* Re: ATC, an example please.
  2005-06-30  8:44 ATC, an example please e.coli
  2005-06-30  9:32 ` Dmitry A. Kazakov
@ 2005-06-30  9:32 ` e.coli
  2005-07-02  8:18 ` Craig Carey
  2 siblings, 0 replies; 9+ messages in thread
From: e.coli @ 2005-06-30  9:32 UTC (permalink / raw)


ps 
i use gnat 3.15p on windows XP




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

* Re: ATC, an example please.
  2005-06-30  9:32 ` Dmitry A. Kazakov
@ 2005-06-30  9:59   ` e.coli
  2005-06-30 11:06   ` Christoph Grein
  2005-06-30 12:55   ` Robert A Duff
  2 siblings, 0 replies; 9+ messages in thread
From: e.coli @ 2005-06-30  9:59 UTC (permalink / raw)


Dmitry A. Kazakov ha scritto:


Ok, now it work.

>
> ----------------------
> N.B. This is a wrong way to do things. Don't use ATC if you cannot prove
> that there is no other way. Don't abort task, which is even more brutal
> than ATC.

http://groups.google.it/group/comp.lang.ada/msg/9ee44544cce5c367?dmode=source&hl=it

:) right?

thanks again




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

* Re: ATC, an  example please.
  2005-06-30  9:32 ` Dmitry A. Kazakov
  2005-06-30  9:59   ` e.coli
@ 2005-06-30 11:06   ` Christoph Grein
  2005-06-30 12:55   ` Robert A Duff
  2 siblings, 0 replies; 9+ messages in thread
From: Christoph Grein @ 2005-06-30 11:06 UTC (permalink / raw)
  To: comp.lang.ada

Try the following variant of Dmitry A. Kazakov's code:

with Ada.Text_IO;

procedure ATC_Test is

  task A_Task is
    entry Start;
    entry Ready;
  end A_Task;

  task body A_Task is
  begin
    loop
      accept Start;
      Ada.Text_IO.Put_Line ("Start");
      for Iteration in 1..100_000 loop
        Ada.Text_IO.Put (".");
        delay 0.01;
      end loop;
      accept Ready;
      Ada.Text_IO.Put_Line ("Ready");
    end loop;
  end A_Task;

begin

  A_Task.Start;          -- Initiate calculation.

  select
    delay 2.0;           -- After time-out expiration, only transfer of 
control.
    Ada.Text_IO.Put_Line ("Expiration");
    delay 1.0;           -- A_Task still alive and running.
    abort A_Task;        -- Kill the task!
    Ada.Text_IO.Put_Line ("Long calculation abandoned");
  then
    abort A_Task.Ready;  -- Wait for completion.
    Ada.Text_IO.Put_Line ("Long calculation completed");
  end select;

  Ada.Text_IO.Put_Line ("End");

end ATC_Test;




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

* Re: ATC, an  example please.
  2005-06-30  9:32 ` Dmitry A. Kazakov
  2005-06-30  9:59   ` e.coli
  2005-06-30 11:06   ` Christoph Grein
@ 2005-06-30 12:55   ` Robert A Duff
  2005-06-30 15:29     ` Dmitry A. Kazakov
  2 siblings, 1 reply; 9+ messages in thread
From: Robert A Duff @ 2005-06-30 12:55 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> ATC transfers control, it does not abort any other task.

Well, it does abort any tasks inside the abortable region of the ATC.
The task in this example could be moved inside the ATC,
and then it would be aborted automatically.

But I was under the impression that the original poster wanted to abort
the processing inside the accept statement, and allow the task to loop
back and accept entry calls again.

I don't see the point of splitting into the Start and Ready entries,
since the caller isn't doing anything useful in between.

> N.B. This is a wrong way to do things. Don't use ATC if you cannot prove
> that there is no other way.

Yes.  It is very difficult to program correctly when there are aborts
(which includes ATC) lurking in the program.  If you call any
third-party code from an abortable place, you need to inspect
every line of it.

>... Don't abort task, which is even more brutal
> than ATC.

Not really.  They both abort some code asynchronously,
and whatever variables are written by that code will be
destroyed in an unpredictable manner.  The issues are
the same for aborting a task as they are for aborting
the abortable part of an ATC.

Storage leaks are another issue with aborts (both kinds).

- Bob



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

* Re: ATC, an  example please.
  2005-06-30 12:55   ` Robert A Duff
@ 2005-06-30 15:29     ` Dmitry A. Kazakov
  2005-06-30 20:31       ` Robert A Duff
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2005-06-30 15:29 UTC (permalink / raw)


On 30 Jun 2005 08:55:27 -0400, Robert A Duff wrote:

> "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:
> 
>> ATC transfers control, it does not abort any other task.
> 
> Well, it does abort any tasks inside the abortable region of the ATC.
> The task in this example could be moved inside the ATC,
> and then it would be aborted automatically.

Yes.

> But I was under the impression that the original poster wanted to abort
> the processing inside the accept statement, and allow the task to loop
> back and accept entry calls again.

Maybe, however it is difficult to see why then there could be any need in
two tasks. During rendezvous they stay synchronous anyway, so it is better
to have a subprogram inside the ATC.

> I don't see the point of splitting into the Start and Ready entries,
> since the caller isn't doing anything useful in between.

Just to mark where the calculation starts...

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



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

* Re: ATC, an  example please.
  2005-06-30 15:29     ` Dmitry A. Kazakov
@ 2005-06-30 20:31       ` Robert A Duff
  0 siblings, 0 replies; 9+ messages in thread
From: Robert A Duff @ 2005-06-30 20:31 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> writes:

> > But I was under the impression that the original poster wanted to abort
> > the processing inside the accept statement, and allow the task to loop
> > back and accept entry calls again.
> 
> Maybe, however it is difficult to see why then there could be any need in
> two tasks. During rendezvous they stay synchronous anyway, so it is better
> to have a subprogram inside the ATC.

Good point.  But we don't know how "oversimplified" the original example
was (compared to the real program they were trying to write).

- Bob



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

* Re: ATC, an  example please.
  2005-06-30  8:44 ATC, an example please e.coli
  2005-06-30  9:32 ` Dmitry A. Kazakov
  2005-06-30  9:32 ` e.coli
@ 2005-07-02  8:18 ` Craig Carey
  2 siblings, 0 replies; 9+ messages in thread
From: Craig Carey @ 2005-07-02  8:18 UTC (permalink / raw)


On 30 Jun 2005 01:44:52 -0700, "e.coli" wrote:

>How [does] ATC work?
>Can you fix this example, please?.


with Ada.Text_IO;
with Ada.Characters.Handling;
with Ada.Exceptions;


procedure ATC_Test is
      --  If compile with gnatmake in Windows, use "-gnatP" polling

   package Tio renames Ada.Text_IO;
   package ACH renames Ada.Characters.Handling;

   procedure Put (X : String) renames Tio.Put;
   procedure PutL (X : String) renames Tio.Put_Line;


   procedure Slave;                 --  This procedure gets interrupted
   procedure Slave is
   begin
            --  Seeming GNAT 3.15p NT bug: Abort_Defer kills the delay
            --  statement (as well as blocking the abort as expected):
      --  pragma Abort_Defer;
      PutL ("Slave starts");
      for Iteration in 1 .. 1_000 loop
         Put (".");
         delay 0.100;
      end loop;
      PutL (ASCII.LF & "Slave ends by itself");
   end Slave;


   task type Keyboard_Task_Type is
      entry Got_Quit_Key;
   end Keyboard_Task_Type;

   type Keyboard_Task_Type_AP is access all Keyboard_Task_Type;

   task body Keyboard_Task_Type
   is
      Ch       : Character;
   begin
      PutL ("Keyboard task starts");
      loop
         Tio.Get_Immediate (Item => Ch);
         Ch := ACH.To_Lower (String'(1 => Ch)) (1);
         PutL (" """ & Ch & '"');
         if Ch = 'q' then
            accept Got_Quit_Key;
            exit;
         end if;
      end loop;
      PutL ("Keyboard task ends");
   exception
      when others => null;
   end Keyboard_Task_Type;


   task type Interruptible_Task is
      entry Start (KT_In : Keyboard_Task_Type_AP);
   end Interruptible_Task;

   task body Interruptible_Task
   is
      KT    : Keyboard_Task_Type_AP;
   begin
      PutL ("Interruptible task starts");
      accept Start (KT_In : Keyboard_Task_Type_AP) do
         KT := KT_In;
      end Start;
      <<REDO>>
      select         --  No aborting when not inside a task
         KT.all.Got_Quit_Key;       --  Now KT maybe becomes unusable
         PutL ("Computation aborted");
      then abort
         PutL ("Starting computation. Press Q to quit");
         Slave;
         PutL ("Finished computation without abrting");
      end select;
      --  goto REDO;             --  If a loop around the select, then
   exception                     --  a "Tasking_Error" error occurs
      when E : others =>         --  when a terminated KT task is used
         PutL ("Interruptible_Task: " &      -- GNAT hides error
                  Ada.Exceptions.Exception_Information (E));
   end Interruptible_Task;

begin
   declare
      KT    : aliased Keyboard_Task_Type;
      IT    : Interruptible_Task;
   begin
      IT.Start (KT_In => KT'Unchecked_Access);
   end;                          --  First declared is last finalized
   PutL ("Main program ends");
end ATC_Test;

% Compiled and run. Only tested in Windows 2003.

$ gnatmake atc_test.adb -gnatP -gnata -gnato -gnatq -O0 -g -gnatf
  -gnatU -m -i -gnatwacfHlpru -gnatR3s -gnaty3abcefhiklM79nprt
  -bargs -E -p -we -s -static -largs -v -v

$ atc_test.exe
---------------------------------------
Keyboard task starts
Interruptible task starts
Starting computation. Press Q to quit
Slave starts
.............. "y"
........ "q"
Keyboard task ends
Computation aborted
Main program ends
---------------------------------------

Perhaps experts (e.g. Mr Obry) can say why GNAT 3.15p ATC:
 (a) only runs inside a task, and/or
 (b) what's up with Abort_Defer feature of disabling the delay statement?.


Craig Carey
Auckland





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

end of thread, other threads:[~2005-07-02  8:18 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-30  8:44 ATC, an example please e.coli
2005-06-30  9:32 ` Dmitry A. Kazakov
2005-06-30  9:59   ` e.coli
2005-06-30 11:06   ` Christoph Grein
2005-06-30 12:55   ` Robert A Duff
2005-06-30 15:29     ` Dmitry A. Kazakov
2005-06-30 20:31       ` Robert A Duff
2005-06-30  9:32 ` e.coli
2005-07-02  8:18 ` Craig Carey

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