comp.lang.ada
 help / color / mirror / Atom feed
From: Esa Riihonen <esa.riihonen.er@gmail.com>
Subject: Re: How to: communication between multiple tasks using protected objects - with no polling?
Date: Thu, 22 Jan 2015 05:32:42 -0800 (PST)
Date: 2015-01-22T05:32:42-08:00	[thread overview]
Message-ID: <537cf2a9-e18d-4efb-adb5-fa1914f48e3a@googlegroups.com> (raw)
In-Reply-To: <m9orn5$2pd$1@dont-email.me>

keskiviikko 21. tammikuuta 2015 20.39.07 UTC+2 Jeffrey Carter kirjoitti:
> On 01/21/2015 10:16 AM, Esa Riihonen wrote:
> > keskiviikko 21. tammikuuta 2015 2.47.29 UTC+2 Jeffrey Carter kirjoitti:
> > 
> >> select
> >>    PO1.Get (...);
> >> then abort
> >>    PO2.Get (...);
> >> end select;
> >>
> >> This might, however, result in both entries being executed.
> > 
> > If I understand correctly this will indeed work when selecting between two PO entries. And it wouldn't matter if both got executed (although I just now can't see how this could happen).
> 
> Why both might be executed is kind of complicated. There was a thread on here
> about this some time ago. Consider the Ada-83 timed entry call:
> 
> select
>    T.E;
> or
>    delay 1.0;
> end select;
> 
> Ada 83 did not have protected types/objects or requeue, so if T.E was accepted
> before the delay expired, the delay could be cancelled. If the delay expired
> before the entry call was accepted then the entry call was aborted.
> 
> Ada 95 introduced protected types/objects and requeue. This changed the
> semantics somewhat. Since the entry call (which can now be to a task or PO
> entry) can be requeued "with abort", the delay can't be canceled when the entry
> call is accepted, since a requeued with abort call can be aborted when the delay
> expires. Instead, we have to wait until the entry call completes before we can
> cancel the delay. If the delay expires while the entry call is being executed,
> that's OK because the execution of an entry call is abort deferred.
> 
> Similar considerations apply to the ATC with both branches being entry calls and
> result in the possibility of both calls being executed.
> 

OK, I think I understand it now. It seems that even Ada is not totally free of its intricasies that can provide some surprises for an uninitiated ;)

> > However, there seems not to be a natural way to expand this for more than
> > those two. This seems to be syntactically correct (compiles):
> > 
> >  select
> >     PO1.Get (...);
> >  then abort
> >     select
> >        PO2.Get (...);
> >     then abort
> >        PO3.Get (...);
> >     end select
> >  end select;
> 
> Yes, these can be nested as far as desired.
> 
> > But I'm not sure whether it would actually do what I want it to do. That is: suspend there until any of the entry barriers becomes true and then exit the whole outermost select statement?
> 
> Yes, but it might execute any number of the entry calls.
> 
> > Even if it works I have a (minor) concern that it is not 'pretty' as it doesn't reflect the mutual equality of the entries - and thus has a feel of 'hack' there ;)
> 
> It's not pretty and it's not a good idea. ATC is said to be a very complex and
> heavyweight construct. I would only use it as a last resort.
> 
> >> type Q_ID is (Q1, Q2, ...);
> >>
> >> type Q_Item (Q : Q_ID := Q_ID'First) is record
> >>    case Q is
> >>    when Q1 =>
> >>       Item_1 : Q1_Item;
> >>    when Q2 =>
> >>       Item_2 : Q2:Item;
> >>    ...
> >>    end case;
> >> end record;
> >>
> >> protected Qs is
> >>    entry Get (Item : out Q_Item);
> >> private -- Qs
> >>    Q_1 : Q1_Q;
> >>    Q_2 : Q2_Q;
> >>    ...
> >> end Qs;
> >>
> >> protected body Qs is
> >>    entry Get (Item : out Q_Item) when
> >>       not Q_1.Is_Empty or not Q_2.Is_Empty or ...
> >>    is
> >>       -- Empty declarative part
> >>    begin -- Get
> >>       if not Q_1.Is_Empty then
> >>          Item := (Q => Q1, Item_1 => Q_1.Get);
> >>       elsif not Q_2.Is_Empty then
> >>          item := (Q => Q2, Item_2 => Q_2.Get;
> >>       ...
> >>       end if;
> >>    end Get;
> >> end Qs;
> 
> I guess I was asleep when I wrote that. For one thing I left out a way to get
> things on the Qs. A better approach would be
> 
> protected Queue is
>    procedure Put (Item : in Q_Item);
>    entry Get (Item : out Q_Item);
> private -- Queue
>    Q : Q_Item_Q;
> end Queue;
> 
> protected body Queue is
>    procedure Put (Item : in Q_Item) is
>       -- Empty declarative part
>    begin -- Put
>       Q.Put (Item => Item);
>    end Put;
> 
>    entry Get (Item : out Q_Item) when not Q.Is_Empty is
>       -- Empty declarative part
>    begin -- Get
>       Q.Get (Item => Item);
>    end Get;
> end Queue;

At least that is more on my level of understanding - thanks.

> If you're willing to restrict yourself to a single compiler vendor, Ada 12 has
> synchronized queues as part of the standard library, and you could use one of
> those instead of writing your own. For earlier versions of Ada, which are
> supported by multiple compiler vendors, you could use PragmARC.Queue_Unbounded
> (or Queue_Bounded) from the PragmAda Reusable Components rather than writing
> your own. I guess it depends on whether writing your own PO is important for
> your learning experience.

Actually I think I at least would have to consider the synch queues in another part of my rehearsal program.

Many thanks for all the help provided.

> -- 
> Jeff Carter
> "Run away! Run away!"
> Monty Python and the Holy Grail
> 58


  reply	other threads:[~2015-01-22 13:32 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-20 22:36 How to: communication between multiple tasks using protected objects - with no polling? Esa Riihonen
2015-01-21  0:19 ` Hubert
2015-01-21 16:53   ` Esa Riihonen
2015-01-21 23:22     ` Hubert
2015-01-22 13:24       ` Esa Riihonen
2015-01-21  0:47 ` Jeffrey Carter
2015-01-21  8:11   ` Simon Wright
2015-01-21 17:16   ` Esa Riihonen
2015-01-21 18:39     ` Jeffrey Carter
2015-01-22 13:32       ` Esa Riihonen [this message]
2015-01-21  8:28 ` Dmitry A. Kazakov
2015-01-21 17:34   ` Esa Riihonen
2015-01-21 18:56     ` Jacob Sparre Andersen
2015-01-21 20:15       ` Dmitry A. Kazakov
2015-01-22 21:52         ` G.B.
2015-01-23  8:25           ` Dmitry A. Kazakov
2015-01-21 20:02     ` Dmitry A. Kazakov
2015-01-22 13:37       ` Esa Riihonen
replies disabled

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