comp.lang.ada
 help / color / mirror / Atom feed
* Newbie: Code isn't executed
@ 2005-08-04 14:10 Thomas Ruschival
  2005-08-04 14:47 ` Ed Falis
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Thomas Ruschival @ 2005-08-04 14:10 UTC (permalink / raw)


Hello Ada group
I am a student learning Ada at university. I played with some tasks
that want to join another task for a rendevouz, its a modiefied exaple
from the lectures. Basically I let 2 tasks sleep a different amount of
time then wake up and execute a piece of code with another task during
a rendevouz, I count the number how often a task got executed.
Somehow a piece of code never gets executed - neither me nor nor my
tutor has a clue why -- here is the code:

Thanks for _ANY_ comments - I know this isn't the best way of coding -
but it was just meant as an example until strange things happened

Thomas


with Ada.Text_IO;
use Ada.Text_IO;

procedure myfirst
is
   type Name is (Peter,Michael);
   type Statistics is array(Name) of Integer;
   Partner : Name;
   Stat : Statistics :=(others => 0);
   Total: Positive :=1000;

   task Michael_task;
   task Peter_task;
   task Susan is
      entry Dinner;
   end Susan;


   task body Peter_task
   is
   begin
      while Total > 0 loop
         Put("Peters turn");
         New_Line;
         Partner := Peter;
         Susan.Dinner;
         delay 0.002;
      end loop;
   end Peter_task;

   task body Michael_task is
   begin
      while Total > 0 loop
         Put("Michaels turn");
         New_Line;
         Partner := Michael;
         Susan.Dinner;
         delay 0.001;
      end loop;
   end Michael_task;


   task body Susan
   is
   begin

      while Total > 0 loop
         Put("susans turn");
         New_Line;
         accept Dinner do
            stat(Partner) := stat(Partner)+1;
            Put("Susan is having dinner with...."& Name'Image(Partner));
            New_Line;
         end Dinner;
         Total := Total-1;
      end loop;

-- THIS WILL NEVER BE EXECUTED --- WHY ??????????????????????
      Put("Statistics:");
      New_Line;
      Put("---------------------------------------------");
      New_Line;
      Put("Peter:  "&Integer'Image(Stat(Peter)));
      New_Line;
      Put("Michael:  "&Integer'Image(Stat(Michael)));
      New_Line;
      Put("---------------------------------------------");
      New_Line;

   end Susan;


begin -- Procedure
   null;
end myfirst;



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

* Re: Newbie: Code isn't executed
  2005-08-04 14:10 Newbie: Code isn't executed Thomas Ruschival
@ 2005-08-04 14:47 ` Ed Falis
  2005-08-04 14:48 ` Egil Høvik
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Ed Falis @ 2005-08-04 14:47 UTC (permalink / raw)


Change Total's type from Positive to Natural.  The Susan task is getting  
an exception when it decrements Total to 0.



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

* Re: Newbie: Code isn't executed
  2005-08-04 14:10 Newbie: Code isn't executed Thomas Ruschival
  2005-08-04 14:47 ` Ed Falis
@ 2005-08-04 14:48 ` Egil Høvik
  2005-08-04 15:07 ` Martin Dowie
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 13+ messages in thread
From: Egil Høvik @ 2005-08-04 14:48 UTC (permalink / raw)



Thomas Ruschival wrote:
> Hello Ada group
> I am a student learning Ada at university. I played with some tasks
> that want to join another task for a rendevouz, its a modiefied exaple
> from the lectures. Basically I let 2 tasks sleep a different amount of
> time then wake up and execute a piece of code with another task during
> a rendevouz, I count the number how often a task got executed.
> Somehow a piece of code never gets executed - neither me nor nor my
> tutor has a clue why -- here is the code:
>
> Thanks for _ANY_ comments - I know this isn't the best way of coding -
> but it was just meant as an example until strange things happened
>
> Thomas
>

Adding an exception handler in the Susan task reveals a
CONSTRAINT_ERROR when Total becomes 0. You should change Total to be of
type Natural instead of Positive (which can never be 0).

Also you have a possible race condition when using the Partner variable
which could give you wrong statistics. See comments in your code below.

Ada.Text_IO provides a Put_Line procedure so you can write
   Ada.Text_IO.Put_Line("...");
instead of
   Ada.Text_IO.Put("...");
   Ada.Text_IO.New_Line;


>
> with Ada.Text_IO;
> use Ada.Text_IO;
>
> procedure myfirst
> is
>    type Name is (Peter,Michael);
>    type Statistics is array(Name) of Integer;
>    Partner : Name;
>    Stat : Statistics :=(others => 0);
>    Total: Positive :=1000;

Should be Total : Natural;

>
>    task Michael_task;
>    task Peter_task;
>    task Susan is
>       entry Dinner;


To avoid a possible race condition you probably want peter and michael
to tell susan who they are directly in the rendezvous, and not use the
"global" variable Partner:

entry Dinner( Partner : Name );

>    end Susan;
>
>
>    task body Peter_task
>    is
>    begin
>       while Total > 0 loop
>          Put("Peters turn");
>          New_Line;
>          Partner := Peter;
>          Susan.Dinner;

Susan.Dinner(Peter);

>          delay 0.002;
>       end loop;
>    end Peter_task;
>
>    task body Michael_task is
>    begin
>       while Total > 0 loop
>          Put("Michaels turn");
>          New_Line;
>          Partner := Michael;
>          Susan.Dinner;

Susan.Dinner(Michael);

>          delay 0.001;
>       end loop;
>    end Michael_task;
>
>
>    task body Susan
>    is
>    begin
>
>       while Total > 0 loop
>          Put("susans turn");
>          New_Line;
>          accept Dinner do

accept Dinner( Parnter : Name ) do

>             stat(Partner) := stat(Partner)+1;
>             Put("Susan is having dinner with...."& Name'Image(Partner));
>             New_Line;
>          end Dinner;
>          Total := Total-1;
>       end loop;
>
> -- THIS WILL NEVER BE EXECUTED --- WHY ??????????????????????
>       Put("Statistics:");
>       New_Line;
>       Put("---------------------------------------------");
>       New_Line;
>       Put("Peter:  "&Integer'Image(Stat(Peter)));
>       New_Line;
>       Put("Michael:  "&Integer'Image(Stat(Michael)));
>       New_Line;
>       Put("---------------------------------------------");
>       New_Line;
> 
>    end Susan;
> 
> 
> begin -- Procedure
>    null;
> end myfirst;




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

* Re: Newbie: Code isn't executed
  2005-08-04 14:10 Newbie: Code isn't executed Thomas Ruschival
  2005-08-04 14:47 ` Ed Falis
  2005-08-04 14:48 ` Egil Høvik
@ 2005-08-04 15:07 ` Martin Dowie
  2005-08-04 17:37   ` tmoran
  2005-08-04 20:20   ` Simon Wright
  2005-08-04 15:09 ` Martin Dowie
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 13+ messages in thread
From: Martin Dowie @ 2005-08-04 15:07 UTC (permalink / raw)


Thomas Ruschival wrote:
>    Total: Positive :=1000;
...
>       while Total > 0 loop
...
>          Total := Total-1;

Because Total is a Positive of range 1 .. Integer'Last, so it can never be 0
(it will raise an exception and dying silently...)

Total : Integer := 1000;

exception
   when others =>
      Put_Line ("Oops!");
end Susan;

would have stopped it being silent.

Also, sharing Total between the tasks is poor, it should be a protected
object.

And finally, what's wrong with Put_Line (instead of Put/New_Line pairs)?

Cheers

-- Martin





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

* Re: Newbie: Code isn't executed
  2005-08-04 14:10 Newbie: Code isn't executed Thomas Ruschival
                   ` (2 preceding siblings ...)
  2005-08-04 15:07 ` Martin Dowie
@ 2005-08-04 15:09 ` Martin Dowie
  2005-08-04 16:37 ` SOLVED: " Thomas Ruschival
  2005-08-05  2:43 ` Steve
  5 siblings, 0 replies; 13+ messages in thread
From: Martin Dowie @ 2005-08-04 15:09 UTC (permalink / raw)


Thomas Ruschival wrote:
> I am a student learning Ada at university. I played with some tasks

p.s. which University?





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

* SOLVED: Newbie: Code isn't executed
  2005-08-04 14:10 Newbie: Code isn't executed Thomas Ruschival
                   ` (3 preceding siblings ...)
  2005-08-04 15:09 ` Martin Dowie
@ 2005-08-04 16:37 ` Thomas Ruschival
  2005-08-05  2:43 ` Steve
  5 siblings, 0 replies; 13+ messages in thread
From: Thomas Ruschival @ 2005-08-04 16:37 UTC (permalink / raw)


thank all,
that solved the problem.

Thomas Ruschival



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

* Re: Newbie: Code isn't executed
  2005-08-04 15:07 ` Martin Dowie
@ 2005-08-04 17:37   ` tmoran
  2005-08-04 20:57     ` Randy Brukardt
  2005-08-04 20:20   ` Simon Wright
  1 sibling, 1 reply; 13+ messages in thread
From: tmoran @ 2005-08-04 17:37 UTC (permalink / raw)


>Also, sharing Total between the tasks is poor, it should be a protected
>object.
  Worse, suppose Peter checks Total while Susan is dining with Michael.
Peter finds Total = 1 so he tries to rendezvous with Susan.  But Susan,
on returning from dinner, decrements Total, finds it to be zero,
prints statistics, and goes away.  Leaving poor Peter still trying to
rendezvous.
  You need a way for Peter and Michael to tell that Susan has gone away
and they should stop calling.  Anything that involves "find out if Susan
is taking calls, and if so call her" will fail if she leaves in the
interval between test and call.  Since dinner is a time-limited event,
they could use a select with timeout.  If she hasn't responded within a
reasonable time, they can give up.



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

* Re: Newbie: Code isn't executed
  2005-08-04 15:07 ` Martin Dowie
  2005-08-04 17:37   ` tmoran
@ 2005-08-04 20:20   ` Simon Wright
  1 sibling, 0 replies; 13+ messages in thread
From: Simon Wright @ 2005-08-04 20:20 UTC (permalink / raw)


"Martin Dowie" <martin.dowie@baesystems.com> writes:

> Because Total is a Positive of range 1 .. Integer'Last, so it can never be 0
> (it will raise an exception and dying silently...)
>
> Total : Integer := 1000;
>
> exception
>    when others =>
>       Put_Line ("Oops!");
> end Susan;
>
> would have stopped it being silent.

If you are using GNAT try this at the start of your main program:

   GNAT.Exception_Traces.Trace_On
     (Kind => GNAT.Exception_Traces.Unhandled_Raise);

Also use the -E argument to gnatbind (gnatmake ... -bargs -E)



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

* Re: Newbie: Code isn't executed
  2005-08-04 17:37   ` tmoran
@ 2005-08-04 20:57     ` Randy Brukardt
  2005-08-05  6:11       ` Vinzent 'Gadget' Hoefler
  0 siblings, 1 reply; 13+ messages in thread
From: Randy Brukardt @ 2005-08-04 20:57 UTC (permalink / raw)


<tmoran@acm.org> wrote in message news:Ht6dndDMFPbLz2_fRVn-uQ@comcast.com...
> >Also, sharing Total between the tasks is poor, it should be a protected
> >object.
>   Worse, suppose Peter checks Total while Susan is dining with Michael.
> Peter finds Total = 1 so he tries to rendezvous with Susan.  But Susan,
> on returning from dinner, decrements Total, finds it to be zero,
> prints statistics, and goes away.  Leaving poor Peter still trying to
> rendezvous.

This sounds like the real world....

>   You need a way for Peter and Michael to tell that Susan has gone away
> and they should stop calling.  Anything that involves "find out if Susan
> is taking calls, and if so call her" will fail if she leaves in the
> interval between test and call.  Since dinner is a time-limited event,
> they could use a select with timeout.  If she hasn't responded within a
> reasonable time, they can give up.

...and so does this. [Giving up, that is, seems to be my primary condition
when dating...] (Sorry, not much to do with Ada! :-)

                        Randy.






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

* Re: Newbie: Code isn't executed
  2005-08-04 14:10 Newbie: Code isn't executed Thomas Ruschival
                   ` (4 preceding siblings ...)
  2005-08-04 16:37 ` SOLVED: " Thomas Ruschival
@ 2005-08-05  2:43 ` Steve
  2005-08-06  5:33   ` Jeffrey Carter
  5 siblings, 1 reply; 13+ messages in thread
From: Steve @ 2005-08-05  2:43 UTC (permalink / raw)


"Thomas Ruschival" <Thomas@ruschival.de> wrote in message 
news:20050804161000.1ffa591b@localhost...
> Hello Ada group
> I am a student learning Ada at university. I played with some tasks
> that want to join another task for a rendevouz, its a modiefied exaple
> from the lectures. Basically I let 2 tasks sleep a different amount of
> time then wake up and execute a piece of code with another task during
> a rendevouz, I count the number how often a task got executed.
> Somehow a piece of code never gets executed - neither me nor nor my
> tutor has a clue why -- here is the code:
>
> Thanks for _ANY_ comments - I know this isn't the best way of coding -
> but it was just meant as an example until strange things happened
>
> Thomas
>
First:
  I recommend you add something like:

    EXCEPTION
      WHEN Reason: OTHERS =>
        Ada.Text_IO.Put( "EXCEPTION NAME: " & Exception_Name( Reason) );
        Ada.Text_IO.Put( "EXCEPTION MESSAGE: " & Exception_Message( 
Reason) ) );
        Ada.Text_IO.Put( "EXCEPTION INFORMATION: " & 
Exception_Information( Reason) ) );

To the end of each of task body, at least for experimenting.  This helps to 
eliminate the problem of tasks dying quietly.

Second:
  You may be aware of this, but there are a lot of holes in the program.
  It is generally not safe to have 2 tasks manipulating the same global 
memory without the use of a protected type.  In your example, I think it 
would make more sense to pass information to Susan at Dinner:

task Susan is
  entry Dinner( Partner : Name );
end Susanl

...

Then instead of:
  Partner := Peter;
  Susan.Dinner;

use:
  Susan.Dinner( Peter );

Also, it is a good idea to avoid doing much inside a rendevous other than 
moving data around, so I would suggest changing:

  dinnerPartner : Name;
  ...
  accept Dinner( Partner : Name ) do
     dinnerPartner := Partner;
  end Dinner
  stat(dinnerPartner ) := stat(dinnerPartner )+1;
  Put("Susan is having dinner with...."& Name'Image(dinnerPartner ));
  New_Line;

During the rendevous only one of the threads runs, so I suggest getting it 
over as soon as possible.

Steve
(The Duck)





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

* Re: Newbie: Code isn't executed
  2005-08-04 20:57     ` Randy Brukardt
@ 2005-08-05  6:11       ` Vinzent 'Gadget' Hoefler
  2005-08-06  3:52         ` tmoran
  0 siblings, 1 reply; 13+ messages in thread
From: Vinzent 'Gadget' Hoefler @ 2005-08-05  6:11 UTC (permalink / raw)


Randy Brukardt wrote:

[Rendezvous]
> ...and so does this. [Giving up, that is, seems to be my primary
> condition when dating...] (Sorry, not much to do with Ada! :-)

Oh, I think it is a very good example for the expressiveness of Ada.

"Look, how perfect you can model The Real World(tm) if you just use The
Right Language(tm)."


Vinzent.

-- 
worst case: The wrong assumption there actually is one.



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

* Re: Newbie: Code isn't executed
  2005-08-05  6:11       ` Vinzent 'Gadget' Hoefler
@ 2005-08-06  3:52         ` tmoran
  0 siblings, 0 replies; 13+ messages in thread
From: tmoran @ 2005-08-06  3:52 UTC (permalink / raw)


> Oh, I think it is a very good example for the expressiveness of Ada.
>
> "Look, how perfect you can model The Real World(tm) if you just use The
> Right Language(tm)."
   Perhaps a take-home lesson is "In the real world, if there's any chance
that Susan might leave, marry, die, etc, it would be really unwise for
Peter to simply pine away forever.  Similarly, in a tasking program,
if there's any chance task S might go away, task P should have a timeout
or otherwise be prepared for S's non-acceptance of a rendezvous."



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

* Re: Newbie: Code isn't executed
  2005-08-05  2:43 ` Steve
@ 2005-08-06  5:33   ` Jeffrey Carter
  0 siblings, 0 replies; 13+ messages in thread
From: Jeffrey Carter @ 2005-08-06  5:33 UTC (permalink / raw)


Steve wrote:
> 
> Also, it is a good idea to avoid doing much inside a rendevous other than 
> moving data around, so I would suggest changing:
> 
>   dinnerPartner : Name;
>   ...
>   accept Dinner( Partner : Name ) do
>      dinnerPartner := Partner;
>   end Dinner
>   stat(dinnerPartner ) := stat(dinnerPartner )+1;
>   Put("Susan is having dinner with...."& Name'Image(dinnerPartner ));
>   New_Line;
> 
> During the rendevous only one of the threads runs, so I suggest getting it 
> over as soon as possible.

This models 2 people dining together, so it makes sense to affect both 
tasks.

-- 
Jeff Carter
"Go and boil your bottoms."
Monty Python & the Holy Grail
01



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

end of thread, other threads:[~2005-08-06  5:33 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-08-04 14:10 Newbie: Code isn't executed Thomas Ruschival
2005-08-04 14:47 ` Ed Falis
2005-08-04 14:48 ` Egil Høvik
2005-08-04 15:07 ` Martin Dowie
2005-08-04 17:37   ` tmoran
2005-08-04 20:57     ` Randy Brukardt
2005-08-05  6:11       ` Vinzent 'Gadget' Hoefler
2005-08-06  3:52         ` tmoran
2005-08-04 20:20   ` Simon Wright
2005-08-04 15:09 ` Martin Dowie
2005-08-04 16:37 ` SOLVED: " Thomas Ruschival
2005-08-05  2:43 ` Steve
2005-08-06  5:33   ` Jeffrey Carter

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