comp.lang.ada
 help / color / mirror / Atom feed
From: Jeffrey Carter <jrcarter@acm.org>
Subject: Re: Protected entries requeueing themselves
Date: Sat, 05 May 2001 20:32:40 GMT
Date: 2001-05-05T20:32:40+00:00	[thread overview]
Message-ID: <3AF46357.59923199@acm.org> (raw)
In-Reply-To: 9cv3j3$h5m$1@news.netmar.com

adam@irvine.com wrote:
> 
>     protected PR is
>         entry E1 (Min_Count : in integer;  Result : out integer);
>         procedure PROC1;
>     private
>         Count : integer := 0;
>     end PR;
> 
> Suppose PROC1 increments Count.  The intent of E1 is for each calling
> task to wait until Count has been incremented past whichever point
> that task desires.  This is illegal:
> 
>     entry E1 (Min_Count : in integer;  Result : out integer)
>                   when Min_Count >= Count is ...
> 
> Intuitively, it seems like this should work:
> 
>     entry E1 (Min_Count : in integer;  Result : out integer) when True is
>     begin
>         if Min_Count < Count then
>             requeue E1;
>         end if;
>         Result := ...
> 
> with the intended effect being that after PROC1 is called, all the
> entries on E1 will be executed to check their Min_Count, and those
> that don't meet the requirement will requeue themselves, while those
> that do will complete.
> 
> But I don't think it works.  As I read 9.5.3, it seems that when E1
> requeues itself, the protected action continues, and this includes
> servicing entry queues, and since "servicing of entry queues continues
> until there are no open entries with queued calls" (9.5.3(18)), but
> this entry will always be open and there will always be a queued call
> on it, since the task keeps requeueing itself on the entry.  Thus, the
> result of this is an infinite loop.

That's correct. No one can get the protected object's lock to execute
Proc1, so Count will never change, and this is an infinite loop unless
there are other tasks queued on E1 and a task that is not requeued
changes Count.

> I recognize that 9.5.2(31) suggests using a private entry, but I'm not
> sure how.  If the barrier on the private entry is "when True", the
> same problem occurs; but I can't think what other barrier could be put
> on the private entry to make things work.
> 
> Any suggestions?  How would you implement something like this to
> achieve the intended effect?  Or is my understanding of 9.5.3
> incorrect?

You would use something like

   protected PR is
      entry E1 (Min_Count : in Natural;  Result : out integer);
      procedure Increment;
   private -- PR
      entry E2 (Min_Count : in Natural; Result : out Integer);

      Count             : Natural :=  0;
      Max_Desired_Count : Integer := -1;
   end PR;

   protected body PR is
      procedure Increment is
      begin -- Increment
         Count := Count + 1;
      end Increment;

      entry E1 (...) when True is
      begin -- E1
         if Min_Count < Count then
            Max_Desired_Count := Integer'Max (Max_Desired_Count,
Min_Count);

            requeue E2;
         end if;

         ...
      end E1;

      entry E2 (...) when Count <= Max_Desired_Count is
      begin -- E2
         ...
         if E2'Count <= 0 then
            Max_Desired_Count := -1;
         end if;
      end E2;
   end PR;

This stores up requests until it can Count is suitable for all stored
requests, which is not quite what you were discussing, but has a simpler
solution than your problem while still using requeue for preference
control. HTH.

-- 
Jeff Carter
"Son of a window-dresser."
Monty Python & the Holy Grail



  reply	other threads:[~2001-05-05 20:32 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-05-04 20:31 Protected entries requeueing themselves adam
2001-05-05 20:32 ` Jeffrey Carter [this message]
2001-05-08 19:35 ` Wilhelm Spickermann
replies disabled

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