Discussion:
Some inter thread/component communication questions
Menno Valkema
2016-04-14 09:48:58 UTC
Permalink
Hi Everyone,

I've some questions with regards to Genode synchronization features
between threads and components.

First a question about packet streams:

1) Can we expect the packet streams to deliver packets in order to the
other component as a FIFO? Thus: can we expect the packet submitted
first, to be delivered first at the other component? Also when bursts of
packets are send through the packet stream?

Other questions are with regards to synchronization between multiple
threads within the same component:

2) Say we have 2 threads in the same component, where Thread A needs to
sleep until an event occurs in Thread B. How to address this? If A and B
were components, signals would be the answer. Would signals also work
between threads within the same component or is there some other approach?

3) What if those same 2 threads need to exchange data? When data is
shared between components, shared memory would be the answer. How to
approach this with 2 threads within the same component. Setup a shared
data space? Do those 2 threads share the same heap which we can use for
this exchange?

Thanks for thinking along.

Kind regards, Menno

PS. The first question is a repost, I noticed in my previous email the
subject was partially discarded. Sorry about that.
--
Cyber Security Labs B.V. | Gooimeer 6-31 | 1411 DD Naarden | The
Netherlands | https://nlcsl.com
Norman Feske
2016-04-14 11:20:36 UTC
Permalink
Hello Menno,
Post by Menno Valkema
1) Can we expect the packet streams to deliver packets in order to the
other component as a FIFO? Thus: can we expect the packet submitted
first, to be delivered first at the other component? Also when bursts of
packets are send through the packet stream?
each packet stream has two ring buffers located within the dataspace
shared between the packet source and packet sink.

* One ring buffer contains the packet descriptors of the submitted
packets (submit queue). It is populated by the packet source and
consumed by the packet sink.

* The other ring buffer contains the packet descriptors that were
processed by the sink (acknowledgement queue). It is populated
by the sink and consumed by the source.

Each of both queues are fifo queues. Hence the order of packets
submitted is exactly the same as the order of packets observed at the
receiving side.

However, both queues are independent from each other. E.g., a sink may
take a whole batch of packets out of the submit queue and process the
requests out of order. In this case, the order of packets descriptors
the source receives in the acknowledgement queue will differ from the
order of submissions.
Post by Menno Valkema
Other questions are with regards to synchronization between multiple
2) Say we have 2 threads in the same component, where Thread A needs to
sleep until an event occurs in Thread B. How to address this? If A and B
were components, signals would be the answer. Would signals also work
between threads within the same component or is there some other approach?
Signals can be used between threads of the same component. In some
situations, this is the simplest approach.

Alternatively, you can use a 'Genode::Lock' for the synchronization.
E.g., one thread may wait for another one releasing a blockade using a
'Lock' that is initialized to be in locked state:

Lock lock(Lock::LOCKED);

The to-be sleeping thread A would block on the lock by calling:

lock.lock();

Because the lock was already locked, the attempt to lock it twice will
result in the thread A to block.

The thread B can wake up thread A by releasing the lock:

lock.unlock();

Internally within Genode, we use this approach to synchronize the
startup of threads and in other situations. Please grep for
"Lock::LOCKED" in the source tree to get many examples for this pattern.
Post by Menno Valkema
3) What if those same 2 threads need to exchange data? When data is
shared between components, shared memory would be the answer. How to
approach this with 2 threads within the same component. Setup a shared
data space? Do those 2 threads share the same heap which we can use for
this exchange?
Within a component, all memory is shared between threads. So there is no
need to use a dataspace. You can simply pass a pointer or a reference
for a component-local object to multiple threads. All threads can
directly access it. However, great care must be taken for the
synchronization of such shared state, usually by enforcing mutually
exclusive access to the shared state via a lock.

Cheers
Norman
--
Dr.-Ing. Norman Feske
Genode Labs

http://www.genode-labs.com · http://genode.org

Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden
Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth
Emery
2016-04-14 11:43:27 UTC
Permalink
Post by Menno Valkema
Hi Everyone,
I've some questions with regards to Genode synchronization features
between threads and components.
1) Can we expect the packet streams to deliver packets in order to the
other component as a FIFO? Thus: can we expect the packet submitted
first, to be delivered first at the other component? Also when bursts of
packets are send through the packet stream?
There is a FIFO queue of packets from the source to the sink, and a FIFO
queue of acknowledge packets from the sink back to the source. However,
the sink could dequeue a number of packets and then acknowledge them out
of order. A good component will strive to have minimal state, so it should
be safe to assume that packets will be processed and acknowledged FIFO.
Even if you get into the cases of network coding or disk head seek
optimization, that sort of work would probably be done in a second buffer
at the sink component and you'll still see FIFO behaviour.
Post by Menno Valkema
2) Say we have 2 threads in the same component, where Thread A needs to
sleep until an event occurs in Thread B. How to address this? If A and B
were components, signals would be the answer. Would signals also work
between threads within the same component or is there some other approach?
Signals would work between threads in the same component, but using simple
primatives like locks and semaphores will give you better performance, because
issueing signal capabilities and exchanging signals requires work outside the
component.
Post by Menno Valkema
3) What if those same 2 threads need to exchange data? When data is
shared between components, shared memory would be the answer. How to
approach this with 2 threads within the same component. Setup a shared
data space? Do those 2 threads share the same heap which we can use for
this exchange?
Multiple threads within a component use the same address space, there shouldn't
be any extra work in shared data between threads. You have the option of using
independent heaps on different RAM sessions, but the mapping is still in the
same space.


Correct me anyone if I am wrong,
Emery
Emery
2016-04-14 11:46:03 UTC
Permalink
Yea, what Norman said :)
Menno Valkema
2016-04-14 12:11:02 UTC
Permalink
Hi Norman and Emery,

Thank you for helping me out here! I'll start working with the
techniques you've described.

Cheers, Menno
Post by Emery
Post by Menno Valkema
Hi Everyone,
I've some questions with regards to Genode synchronization features
between threads and components.
1) Can we expect the packet streams to deliver packets in order to the
other component as a FIFO? Thus: can we expect the packet submitted
first, to be delivered first at the other component? Also when bursts of
packets are send through the packet stream?
There is a FIFO queue of packets from the source to the sink, and a FIFO
queue of acknowledge packets from the sink back to the source. However,
the sink could dequeue a number of packets and then acknowledge them out
of order. A good component will strive to have minimal state, so it should
be safe to assume that packets will be processed and acknowledged FIFO.
Even if you get into the cases of network coding or disk head seek
optimization, that sort of work would probably be done in a second buffer
at the sink component and you'll still see FIFO behaviour.
Post by Menno Valkema
2) Say we have 2 threads in the same component, where Thread A needs to
sleep until an event occurs in Thread B. How to address this? If A and B
were components, signals would be the answer. Would signals also work
between threads within the same component or is there some other approach?
Signals would work between threads in the same component, but using simple
primatives like locks and semaphores will give you better performance, because
issueing signal capabilities and exchanging signals requires work outside the
component.
Post by Menno Valkema
3) What if those same 2 threads need to exchange data? When data is
shared between components, shared memory would be the answer. How to
approach this with 2 threads within the same component. Setup a shared
data space? Do those 2 threads share the same heap which we can use for
this exchange?
Multiple threads within a component use the same address space, there shouldn't
be any extra work in shared data between threads. You have the option of using
independent heaps on different RAM sessions, but the mapping is still in the
same space.
Correct me anyone if I am wrong,
Emery
------------------------------------------------------------------------------
Find and fix application performance issues faster with Applications Manager
Applications Manager provides deep performance insights into multiple tiers of
your business applications. It resolves application problems quickly and
reduces your MTTR. Get your free trial!
https://ad.doubleclick.net/ddm/clk/302982198;130105516;z
_______________________________________________
genode-main mailing list
https://lists.sourceforge.net/lists/listinfo/genode-main
Loading...