Some inter thread/component communication questions

Norman Feske norman.feske at ...1...
Thu Apr 14 13:20:36 CEST 2016


Hello Menno,

> 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?

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.

> 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?

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.

> 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




More information about the users mailing list