comp.lang.ada
 help / color / mirror / Atom feed
From: AdaMagica <christoph.grein@eurocopter.com>
Subject: Re: requeue vs requeue with abort - code example pleaseeee
Date: Fri, 10 Dec 2010 02:12:24 -0800 (PST)
Date: 2010-12-10T02:12:24-08:00	[thread overview]
Message-ID: <4b300308-549a-41db-a0e3-961bf9e4f422@l8g2000yqh.googlegroups.com> (raw)
In-Reply-To: 1hvnr1d2wp3vj$.fnxma3y5cxig.dlg@40tude.net

This is an elaborate example for timed entry calls with requeue with
abort.

First note:
There is a also a subtle difference between a conditional entry
call and a timed entry call with zero delay (even though 9.7.3(3) says
that
they are equivalent). If the communication time between caller and
callee
is significant, the timed entry call is cancelled at once, even though
the
callee may be ready to accept. The conditional entry call will succeed
because it will not be cancelled before the request reaches the callee
and the open alternatives are examined (a conditional entry call to a
task
running on Voyager will succeed, a timed one will be cancelled).

Imagine two entries E1 and E2 (not necessarily of the same task; the
client calling E1 might even be oblivious of entry E2.

The client performs a timed entry call with E1, which (unknown to the
client is requeued with abort to E2).

There exist several possibilities that the TEC expires before the
requeued
E2 starts as is shown in the following time tables:

A. TEC delay expires before rendezvous begin of E2.

T0:      TEC E1 with delay D
T1:      rendezvous E1 starts
T2:      E1 requeued with abort to E2 - this ends rendezvous, but TEC
         of T0 continues
T3=T0+D: clients patience expires
         E2 is cancelled - this aborts the TEC (RM 9.7.2(5))

B. TEC delay expires before E1 is requeued to E2, but within
rendezvous

T0:      TEC E1 with delay D
T1:      rendezvous E1 starts
T2=T0+D: delay expires, but since E1 is executing, rendezvous
continues
T3:      requeued with abort to E2 and rendezvous E1 ends

Thus, we now have to distinguish two cases:

(i) E2 is ready for rendezvous:

T3 cont'ed: Entry call E2 is not queued, instead rendezvous E2 starts
            immediately, so entry call of T0 is not cancelled.
            From the client's point of view, the entry call terminates
            normally (because the client is unaware of the requeue).

(ii) E2 is not ready for rendezvous:

T3 cont'ed: Entry call E2 is queued. Since the delay has already
            expired at T2, the entry call E2 is immediately cancelled,
            i.e. taken out of the queue again.
            This is the abortion of the timed entry call at T0
            because the call did not start before the expiration
            (in fact, it's the call of E2 that did not start before
            T2, but the client is unaware of the requeue).

The program below tries to verify this behaviour.
The big delays in the code are just for illustration. In reality,
this would be microseconds.
Imagine the entry E1 is accepted just before the delay expires (it
scrapes
through, so to say). When there is no delay before the requeue, the
task
immediately requeues - but to determine the need to requeue and to do
the
requeue and to terminate the rendezvous need some time,
albeit a tiny amount - just so much that thereafter the delay has
expired.
Now the conditional entry call must fail if E2 is not immediately
ready.

with Ada.Text_IO;
use  Ada.Text_IO;

procedure Timed_Entry_Call is

  task Server is
    entry E1;
  end Server;

  task Hidden is
    entry Start;
    entry E2;
  end Hidden;

  task body Server is
  begin
    loop
      accept E1 do
        Put_Line ("E1 accepted");
        delay 3.0;  -- (1) do some work that takes longer than
client's patience
        Put_Line ("E1 requeued");
        requeue Hidden.E2 with abort;
      end E1;
    end loop;
  end Server;

  task body Hidden is
  begin
    accept Start;
    Put_Line ("E2 ready");
    loop
      accept E2 do
        Put_Line ("E2 accepted");
      end E2;
    end loop;
  end Hidden;

begin

  for I in 1 .. 2 loop

    Put_Line ("Round" & Integer'Image (I));

    select
      Server.E1;  -- E1 is ready for rendezvous
      Put_Line ("E1 done");
    or
      delay 1.0;  -- (2)
      Put_Line ("First time aborting because E2 not ready");
      Hidden.Start;  -- Make E2 ready for second time
    end select;

    delay 1.0;

    New_Line;

  end loop;

  Put_Line ("Done");

  abort Server, Hidden;

end Timed_Entry_Call;

-- Expected result (this is possibility B):

-- Round 1
-- E1 accepted
-- E1 requeued
-- First time aborting because E2 not ready
-- E2 ready
--
-- Round 2
-- E1 accepted
-- E1 requeued
-- E2 accepted
-- E1 done
--
-- Done

This is from some experiments many years ago. I hope it's complete and
works.



  reply	other threads:[~2010-12-10 10:12 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-09 13:57 requeue vs requeue with abort - code example pleaseeee domel
2010-12-09 16:22 ` Dmitry A. Kazakov
2010-12-09 19:00 ` Warren
2010-12-10  0:11   ` Randy Brukardt
2010-12-10  5:52     ` Shark8
2010-12-10  7:14   ` Simon Wright
2010-12-10  8:34   ` Dmitry A. Kazakov
2010-12-10 10:12     ` AdaMagica [this message]
2010-12-10 17:27       ` Robert A Duff
2010-12-11 15:59         ` AdaMagica
2010-12-10 16:11     ` Adam Beneschan
2010-12-10 20:13     ` Warren
2010-12-10 21:30       ` Adam Beneschan
2010-12-10 21:48         ` Simon Wright
2010-12-13 16:21         ` Warren
2010-12-13 19:55           ` Adam Beneschan
2010-12-14 15:40             ` Warren
2010-12-11  0:46       ` Peter C. Chapin
2010-12-11  1:39         ` Adam Beneschan
replies disabled

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