pravu pp
pravu pp

Reputation: 882

Tasks in Ada statement 'accept start do ' is not completing it all execution?

Tasks in Ada 'accept start do ' statement is not completing its all execution ?

accept start do

Here 'do' keyword force compiler to finish all the execution mention between do and end keyword but why in below code its not happen ?why it is printing other task body i.e first(task name) not its own task(i.e start) in the below code? please help me to understand where i went wrong?

procedure main is
   task first is
      entry start;
   end first;

   task body first is
   begin
      accept start ;   -- i am not using do here

      put_line("first");
      put_line("first");
      put_line("first");
   end first;

   task second is
      entry start;
   end second;

   task body second is
   begin
      accept start do -- here 'do' keyword will force compile to finish all the execution between keyword 'do' and end? but why it is mixing statement of task first? 
         for i in 1..10 loop
            put_line("second");
         end loop;
      end start;
   end second;

begin
   first.start;
   second.start;
end main;

   output-
   second
   second
   second
   second
   first   -- why first get printed between before completing second?
   first
   first
   second
   second
   second
   second
   second
   second

Note-every time its give different o/p i was expecting if task second gets activated first then it should first complete all the statement between do and end it should not print other task statement till second gets finish then its should go for other task

Upvotes: 2

Views: 354

Answers (1)

Simon Wright
Simon Wright

Reputation: 25501

After first.start is accepted, first is ready to output a line whenever it gets a processor, while main carries on and calls second.start.

After second.start is accepted, second outputs its 10 lines before returning control to main.

But, what happens if deep within the Ada runtime system, or even the operating system, it turns out that put_line involves blocking?

In that case, second is blocked, so first is free to carry on and output one of its lines. At which point first is likely to be blocked again, so second gets a chance ...

So it seems that your OS (and mine - Mac OS X) block, or at any rate can block, inside put_line.

Overall, the fact is that standard output - which is what you are accessing via put or put_line - is a shared resource which you are accessing from two tasks. The Ada language (ARM 9(8)) says

tasks can communicate indirectly by reading and updating (unprotected) shared variables, presuming the access is properly synchronized through some other kind of task interaction.

and you are not doing any form of synchronization, so the system can do what it feels like; the results aren’t defined by the language. In similar circumstances I’ve seen one task outputting “hello” and another outputting “world” resulting in “hweolrllod”.

Upvotes: 5

Related Questions