comp.lang.ada
 help / color / mirror / Atom feed
* tasking design considerations
@ 2017-01-20  8:07 rrr.eee.27
  2017-01-20  8:29 ` Björn Lundin
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: rrr.eee.27 @ 2017-01-20  8:07 UTC (permalink / raw)


I am still trapped in old school linear thinking and I am facing a tasking design problem.

On channel A I receive messages in a irregular way. I then have to collect all messages of a given time frame T, process the messages that lie within the time frame and then send out the result to channel B.

For the ease of reasoning you can assume typically around 0 .. 20 messages (the maximum certainly << 1000 messages) per time frame T. The cycle time of T is fixed now to 1 minute, but might go down in the future to 1 second. Channel B of course has exactly one message per T.  The channels are TCP sockets. Reception of a single complete message in channel A activates callback function in my program.

I want now create a protected object stack. The callbacks from channel A fill the stack on the top. A cyclic task with a cycle time T reads and removes all collected messages from the bottom of the stack. The task processes the messages and sends out the result.

Does that sound like a reasonable and feasable design? I'm looking forward to any feedback.

best regards
    RE


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

* Re: tasking design considerations
  2017-01-20  8:07 tasking design considerations rrr.eee.27
@ 2017-01-20  8:29 ` Björn Lundin
  2017-01-20  8:42 ` Dmitry A. Kazakov
  2017-01-20 16:01 ` Jeffrey R. Carter
  2 siblings, 0 replies; 6+ messages in thread
From: Björn Lundin @ 2017-01-20  8:29 UTC (permalink / raw)


On 2017-01-20 09:07, rrr.eee.27@gmail.com wrote:
> I want now create a protected object stack. The callbacks from channel A fill the stack on the top. 
> A cyclic task with a cycle time T reads and removes all collected messages from the bottom of the stack. 

Instead of polling the stack, you could have a an entry with a barrier
in the PO that the task hangs upon.

the PO would then have

  procedure Put_On_Stack(Msg)
  entry Get_From_Stack(Msg) when Cnt > 0;
  function Count return Natural;
  private
    Cnt : Natural := 0;


  Put_On_Stack increases Cnt
  Get_On_Stack decreases Cnt

The task could then do

loop
  Get_From_Stack(msg); -- <-- entry with barrier
  exit when msg = exit_message;
  process(msg)
end loop;

The barrier/guard on the entry would be 'stack is not empty'

and to bring the task down at exit of process,
define an exit message and put that in the bottom of the stack for fast
exit, or on the top if processing the whole stack is more important than
a fast exit

--
Björn

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

* Re: tasking design considerations
  2017-01-20  8:07 tasking design considerations rrr.eee.27
  2017-01-20  8:29 ` Björn Lundin
@ 2017-01-20  8:42 ` Dmitry A. Kazakov
  2017-01-20 12:32   ` rrr.eee.27
  2017-01-20 16:01 ` Jeffrey R. Carter
  2 siblings, 1 reply; 6+ messages in thread
From: Dmitry A. Kazakov @ 2017-01-20  8:42 UTC (permalink / raw)


On 20/01/2017 09:07, rrr.eee.27@gmail.com wrote:
> I am still trapped in old school linear thinking and I am facing a
> tasking design problem.
>
> On channel A I receive messages in a irregular way. I then have to
> collect all messages of a given time frame T, process the messages that
> lie within the time frame and then send out the result to channel B.
 >
> For the ease of reasoning you can assume typically around 0 .. 20
> messages (the maximum certainly << 1000 messages) per time frame T. The
> cycle time of T is fixed now to 1 minute, but might go down in the
> future to 1 second. Channel B of course has exactly one message per T.
> The channels are TCP sockets. Reception of a single complete message in
> channel A activates callback function in my program.
>
> I want now create a protected object stack. The callbacks from
> channel  A fill the stack on the top. A cyclic task with a cycle time T reads and
> removes all collected messages from the bottom of the stack. The task
> processes the messages and sends out the result.
>
> Does that sound like a reasonable and feasable design? I'm looking
> forward to any feedback.

Yes. Two minor notes:

1. It is not a stack (LIFO) it a FIFO, I suppose you want to keep the 
messages ordering.

2. You don't need a protected object or other locking method because a 
FIFO with a single writer and a single reader is task-safe (can be 
designed lock-free).

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


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

* Re: tasking design considerations
  2017-01-20  8:42 ` Dmitry A. Kazakov
@ 2017-01-20 12:32   ` rrr.eee.27
  2017-01-20 14:11     ` Dmitry A. Kazakov
  0 siblings, 1 reply; 6+ messages in thread
From: rrr.eee.27 @ 2017-01-20 12:32 UTC (permalink / raw)


On Friday, January 20, 2017 at 9:42:36 AM UTC+1, Dmitry A. Kazakov wrote:
...
> Yes. Two minor notes:
> 
> 1. It is not a stack (LIFO) it a FIFO, I suppose you want to keep the 
> messages ordering.

OK, yes, it is a FIFO storage.
 
> 2. You don't need a protected object or other locking method because a 
> FIFO with a single writer and a single reader is task-safe (can be 
> designed lock-free).
> 

I don't understand. It might be that the task reading the FIFO starts while a callback is active adding a message to the FIFO. I think there must be a lock to exclude reading and writing the FIFO at the same time.

RE


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

* Re: tasking design considerations
  2017-01-20 12:32   ` rrr.eee.27
@ 2017-01-20 14:11     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 6+ messages in thread
From: Dmitry A. Kazakov @ 2017-01-20 14:11 UTC (permalink / raw)


On 20/01/2017 13:32, rrr.eee.27@gmail.com wrote:
> On Friday, January 20, 2017 at 9:42:36 AM UTC+1, Dmitry A. Kazakov wrote:
> ...
>> 2. You don't need a protected object or other locking method because a
>> FIFO with a single writer and a single reader is task-safe (can be
>> designed lock-free).
>
> I don't understand. It might be that the task reading the FIFO
> starts  while a callback is active adding a message to the FIFO. I think there
> must be a lock to exclude reading and writing the FIFO at the same time.

No. The idea is as follows. The FIFO is a ring buffer. Reader moves the 
out-index in the buffer. Writer does the in-index (after placing an 
element). Index I/O is atomic. The space to read is between out- and 
in-indices. The space to write in outside that. They don't overlap, thus 
no exclusion is needed.

[ You can find an implementation here 
http://www.dmitry-kazakov.de/ada/components.htm#10.1 ]
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de


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

* Re: tasking design considerations
  2017-01-20  8:07 tasking design considerations rrr.eee.27
  2017-01-20  8:29 ` Björn Lundin
  2017-01-20  8:42 ` Dmitry A. Kazakov
@ 2017-01-20 16:01 ` Jeffrey R. Carter
  2 siblings, 0 replies; 6+ messages in thread
From: Jeffrey R. Carter @ 2017-01-20 16:01 UTC (permalink / raw)


On 01/20/2017 09:07 AM, rrr.eee.27@gmail.com wrote:
>
> For the ease of reasoning you can assume typically around 0 .. 20 messages
> (the maximum certainly << 1000 messages) per time frame T. The cycle time of
> T is fixed now to 1 minute, but might go down in the future to 1 second.
> Channel B of course has exactly one message per T.  The channels are TCP
> sockets. Reception of a single complete message in channel A activates
> callback function in my program.

Callbacks are usually a mechanism used to deal with concurrency in a sequential 
language. When you have a concurrent language, use of callbacks is usually a 
poor design.

> I want now create a protected object stack. The callbacks from channel A fill
> the stack on the top. A cyclic task with a cycle time T reads and removes all
> collected messages from the bottom of the stack. The task processes the
> messages and sends out the result.

This is a queue, not a stack.

This seems like a reasonable design. The only question is how task B decides 
which messages to include for a time frame. If B reads until the queue is empty, 
it may read msgs that belong in the next time frame. One way to avoid this is to 
have B obtain the length of the Q and read that many msgs. Another is for B to 
invoke an operation that gives B a copy of the Q and clears the Q.

-- 
Jeff Carter
"Frankie Wolf, wanted by Federal authorities for
dancing with a mailman."
Take the Money and Run
143


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

end of thread, other threads:[~2017-01-20 16:01 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-20  8:07 tasking design considerations rrr.eee.27
2017-01-20  8:29 ` Björn Lundin
2017-01-20  8:42 ` Dmitry A. Kazakov
2017-01-20 12:32   ` rrr.eee.27
2017-01-20 14:11     ` Dmitry A. Kazakov
2017-01-20 16:01 ` Jeffrey R. Carter

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