comp.lang.ada
 help / color / mirror / Atom feed
* How do I get an enctry in a protected object to block until a certain item arrives from a producer task?
@ 2016-08-23 17:15 john
  2016-08-23 17:52 ` Egil H H
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: john @ 2016-08-23 17:15 UTC (permalink / raw)


Hi! I've also asked this on Stackoverflow because I'm really stuck with this. I have a protected object that contains an ordered hash map. It stored events by their id as they are provided by some producer task. Now one or more consumer tasks can obtain these events, but I need a call that blocks the consumer until a given id has arrived while the producer continues producing. So a simple barrier doesn't work.

I can't find a directly applicable design pattern in my Ada books for this, although I imagine this is some kind of FAQ.

Here is the relevant code snippet:

   package Reply_Storage is new Ada.Containers.Indefinite_Ordered_Maps
     (Key_Type     => Command_Id_Type,
      Element_Type => Event_Type);

   protected type Reply_Queue is
      procedure Put (Event : Event_Type);
      entry Take (Id : Command_Id_Type; Event : out Event_Type);
   private
      Storage : Reply_Storage.Map;
   end Reply_Queue;

   protected body Reply_Queue is
      procedure Put (Event : Event_Type) is
         Id : Command_Id_Type := Event_Command_Id (Event);
      begin
         Storage.Insert (Id, Event);
      end Put;
      entry Take (Id : Command_Id_Type; Event : out Event_Type)
       when not Storage.Is_Empty is
      begin
         if Storage.Contains(Id) then
           Event := Storage.Element (Id);
            Storage.Delete (Id);
         end if;
      end Take;
   end Reply_Queue;

Basically, instead of not Storage.Is_Empty, I'd not the condition Storage.Contains(Id). The consumer should block until the map has received the event with the given id. But I don't know how. :/

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

* Re: How do I get an enctry in a protected object to block until a certain item arrives from a producer task?
  2016-08-23 17:15 How do I get an enctry in a protected object to block until a certain item arrives from a producer task? john
@ 2016-08-23 17:52 ` Egil H H
  2016-08-23 19:26   ` J-P. Rosen
  2016-08-23 19:44 ` Dmitry A. Kazakov
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Egil H H @ 2016-08-23 17:52 UTC (permalink / raw)


On Tuesday, August 23, 2016 at 7:15:46 PM UTC+2, Some Dude wrote:
> Hi! I've also asked this on Stackoverflow because I'm really stuck with 

I just answered this on stackoverflow. If Command_Id_Type is a discrete type, what you need is an entry family (which is like an array of entries)
see the stackoverflow answer for an example


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

* Re: How do I get an enctry in a protected object to block until a certain item arrives from a producer task?
  2016-08-23 17:52 ` Egil H H
@ 2016-08-23 19:26   ` J-P. Rosen
  2016-08-23 20:02     ` Jeffrey R. Carter
  0 siblings, 1 reply; 10+ messages in thread
From: J-P. Rosen @ 2016-08-23 19:26 UTC (permalink / raw)


Le 23/08/2016 à 19:52, Egil H H a écrit :
> On Tuesday, August 23, 2016 at 7:15:46 PM UTC+2, Some Dude wrote:
>> Hi! I've also asked this on Stackoverflow because I'm really stuck with 
> 
> I just answered this on stackoverflow. If Command_Id_Type is a discrete type, what you need is an entry family (which is like an array of entries)
> see the stackoverflow answer for an example
> 
Or accept the entry, and if the proper data is not there, requeue.

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr

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

* Re: How do I get an enctry in a protected object to block until a certain item arrives from a producer task?
  2016-08-23 17:15 How do I get an enctry in a protected object to block until a certain item arrives from a producer task? john
  2016-08-23 17:52 ` Egil H H
@ 2016-08-23 19:44 ` Dmitry A. Kazakov
  2016-08-24  9:49   ` Mark Lorenzen
  2016-08-23 21:34 ` Some Dude
  2016-08-23 21:37 ` Some Dude
  3 siblings, 1 reply; 10+ messages in thread
From: Dmitry A. Kazakov @ 2016-08-23 19:44 UTC (permalink / raw)


On 2016-08-23 19:15, john@peppermind.com wrote:
> Hi! I've also asked this on Stackoverflow because I'm really stuck
> with this. I have a protected object that contains an ordered hash map.
> It stored events by their id as they are provided by some producer task.
> Now one or more consumer tasks can obtain these events, but I need a
> call that blocks the consumer until a given id has arrived while the
> producer continues producing. So a simple barrier doesn't work.
>
> I can't find a directly applicable design pattern in my Ada books
> for  this, although I imagine this is some kind of FAQ.

The universal pattern for this I call the "lounge pattern". It allows 
waiting for some condition that cannot be evaluated as a barrier or 
requires too many different entries (a large family of entries).

Examples are waiting for a combination of events or for a specific real 
value or set of values, etc.

The idea is as follows. You have the original entry with the parameter 
that is used to evaluate the condition ending waiting. The entry has no 
barrier. Then you have two private entries with the same parameter or a 
family of entries parametrized by Boolean, these are the "lounge". The 
lounge entries have the barrier that is True for one and False for another.

You call the public entry. Within it you evaluate the condition. If 
satisfied you are done. If not you requeue to the lounge entry that is 
currently closed.

You toggle barriers of the lounge entries when it makes sense to 
reevaluate a condition. That opens the closed lounge entry. In the entry 
you evaluate the condition using the parameter. Again if not satisfied 
you requeue to another entry and keep on waiting.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

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

* Re: How do I get an enctry in a protected object to block until a certain item arrives from a producer task?
  2016-08-23 19:26   ` J-P. Rosen
@ 2016-08-23 20:02     ` Jeffrey R. Carter
  0 siblings, 0 replies; 10+ messages in thread
From: Jeffrey R. Carter @ 2016-08-23 20:02 UTC (permalink / raw)


On 08/23/2016 12:26 PM, J-P. Rosen wrote:
> Le 23/08/2016 à 19:52, Egil H H a écrit :
>>
>> I just answered this on stackoverflow. If Command_Id_Type is a discrete type, what you need is an entry family (which is like an array of entries)
>> see the stackoverflow answer for an example
>>
> Or accept the entry, and if the proper data is not there, requeue.

This is called Preference Control, "where the ability to satisfy a request
depends on the parameters passed in". An example is given in AARM-95 9.2.1

http://www.adaic.org/resources/add_content/standards/95rat/rat95html/rat95-p2-9.html#2

-- 
Jeff Carter
"I've seen projects fail miserably for blindly
applying the Agile catechism: we're Agile, we
don't need to stop and think, we just go ahead
and code!"
Bertrand Meyer
150

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

* Re: How do I get an enctry in a protected object to block until a certain item arrives from a producer task?
  2016-08-23 17:15 How do I get an enctry in a protected object to block until a certain item arrives from a producer task? john
  2016-08-23 17:52 ` Egil H H
  2016-08-23 19:44 ` Dmitry A. Kazakov
@ 2016-08-23 21:34 ` Some Dude
  2016-08-23 22:28   ` Jeffrey R. Carter
  2016-08-23 21:37 ` Some Dude
  3 siblings, 1 reply; 10+ messages in thread
From: Some Dude @ 2016-08-23 21:34 UTC (permalink / raw)


Thanks a lot! I think I will have to switch to Dmitry's suggestion with the requeue approach. Here is Egil's modification from Stackexchange:

   protected type Reply_Queue is
      procedure Put (Event : Event_Type);
      entry Take (Command_Id_Type) (Event : out Event_Type);
   private
      Storage : Reply_Storage.Map;
   end Reply_Queue;

   protected body Reply_Queue is
      procedure Put (Event : Event_Type) is
         Id : Command_Id_Type := Event_Command_Id (Event);
      begin
         Storage.Insert (Id, Event);
      end Put;
      entry Take (for Id in Command_Id_Type) (Event : out Event_Type)
       when Storage.Contains(Id) is
      begin
         Event := Storage.Element (Id);
         Storage.Delete (Id);
      end Take;
   end Reply_Queue;

Curiously, it does not work for this definition:

subtype Command_Id_Type is Natural;

But compiles first for this one:

type Command_Id_Type is new Integer range 0 .. Integer'Last-1;

However, linking fails:

/home/nemo/git/ada/bham/obj/bham.o: In function `bham__connection_handlerTKB':
bham.adb:(.text+0x1300a): relocation truncated to fit: R_X86_64_32 against `.bss'
/home/nemo/git/ada/bham/obj/bham.o: In function `bham__open_local_connection':
bham.adb:(.text+0x143ca): relocation truncated to fit: R_X86_64_PC32 against `.bss'
/home/nemo/git/ada/bham/obj/bham.o: In function `bham__close_all':
bham.adb:(.text+0x14415): relocation truncated to fit: R_X86_64_PC32 against `.bss'
/home/nemo/git/ada/bham/obj/bham.o: In function `bham__send_sync':
bham.adb:(.text+0x145aa): relocation truncated to fit: R_X86_64_PC32 against `.bss'
/home/nemo/git/ada/bham/obj/bham.o: In function `bham__finalize_body':
bham.adb:(.text+0x15c9b): relocation truncated to fit: R_X86_64_32 against `.bss'
/home/nemo/git/ada/bham/obj/bham.o: In function `bham___elabb':
bham.adb:(.text+0x161f0): relocation truncated to fit: R_X86_64_32 against `.bss'
bham.adb:(.text+0x16203): relocation truncated to fit: R_X86_64_32 against `.bss'
bham.adb:(.text+0x16250): relocation truncated to fit: R_X86_64_32 against `.bss'
collect2: error: ld returned 1 exit status
gprbuild: link of test.adb failed
[2016-08-23 22:11:53] process exited with status 4, 100% (3/3), elapsed time: 01.36s

What do these messages even mean?

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

* Re: How do I get an enctry in a protected object to block until a certain item arrives from a producer task?
  2016-08-23 17:15 How do I get an enctry in a protected object to block until a certain item arrives from a producer task? john
                   ` (2 preceding siblings ...)
  2016-08-23 21:34 ` Some Dude
@ 2016-08-23 21:37 ` Some Dude
  3 siblings, 0 replies; 10+ messages in thread
From: Some Dude @ 2016-08-23 21:37 UTC (permalink / raw)


Addendum: Seems GNAT wanted a 32 bit integer type even though I'm on a 64 bit machine. I made a subtype with a smaller range and it compiled and linked fine.


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

* Re: How do I get an enctry in a protected object to block until a certain item arrives from a producer task?
  2016-08-23 21:34 ` Some Dude
@ 2016-08-23 22:28   ` Jeffrey R. Carter
  0 siblings, 0 replies; 10+ messages in thread
From: Jeffrey R. Carter @ 2016-08-23 22:28 UTC (permalink / raw)


On 08/23/2016 02:34 PM, Some Dude wrote:
> 
> But compiles first for this one:
> 
> type Command_Id_Type is new Integer range 0 .. Integer'Last-1;
> 
> However, linking fails:
> ...
> What do these messages even mean?

Presumably that there's not enough room for Integer'Last entry queues.

-- 
Jeff Carter
"I've seen projects fail miserably for blindly
applying the Agile catechism: we're Agile, we
don't need to stop and think, we just go ahead
and code!"
Bertrand Meyer
150


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

* Re: How do I get an enctry in a protected object to block until a certain item arrives from a producer task?
  2016-08-23 19:44 ` Dmitry A. Kazakov
@ 2016-08-24  9:49   ` Mark Lorenzen
  2016-08-24 10:26     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Lorenzen @ 2016-08-24  9:49 UTC (permalink / raw)


On Tuesday, August 23, 2016 at 9:44:26 PM UTC+2, Dmitry A. Kazakov wrote:
> 
> [snip]
>
> The universal pattern for this I call the "lounge pattern". It allows 
> waiting for some condition that cannot be evaluated as a barrier or 
> requires too many different entries (a large family of entries).

Dmitry,

I have noticed that you often refer to named patterns in discussions here on c.l.a. Can you recommend a good reference for patterns?

Regards,

Mark L


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

* Re: How do I get an enctry in a protected object to block until a certain item arrives from a producer task?
  2016-08-24  9:49   ` Mark Lorenzen
@ 2016-08-24 10:26     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 10+ messages in thread
From: Dmitry A. Kazakov @ 2016-08-24 10:26 UTC (permalink / raw)


On 24/08/2016 11:49, Mark Lorenzen wrote:

> I have noticed that you often refer to named patterns in discussions
> here on c.l.a. Can you recommend a good reference for patterns?

I cannot. There are lots of resources on software patterns, but in my 
opinion if a pattern is not self-evident, e,g. MVC, it is useless. Most 
patterns are too obscured or too specific to be worth studying. Except 
maybe for language designers, because all more or less elaborated 
patterns are results of language weaknesses. But then it must be Ada 
[anti-]patterns:

       ...
    elsif X in T'Class -- Ada designers, please fix this mess!
       declare
          Object : T'Class renames T'Class (X);
       begin
          ...
       end;
    elsif
       ...

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


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

end of thread, other threads:[~2016-08-24 10:26 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-23 17:15 How do I get an enctry in a protected object to block until a certain item arrives from a producer task? john
2016-08-23 17:52 ` Egil H H
2016-08-23 19:26   ` J-P. Rosen
2016-08-23 20:02     ` Jeffrey R. Carter
2016-08-23 19:44 ` Dmitry A. Kazakov
2016-08-24  9:49   ` Mark Lorenzen
2016-08-24 10:26     ` Dmitry A. Kazakov
2016-08-23 21:34 ` Some Dude
2016-08-23 22:28   ` Jeffrey R. Carter
2016-08-23 21:37 ` Some Dude

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