Multi-threading and synchronization

Threads

A thread is created by constructing an object of a class inherited from Thread. The new thread starts its execution at the entry method. Thereby, each thread runs in the context of its object and can access context-specific information by accessing its member variables. This largely alleviates the need for a thread-local storage (TLS) mechanism. Threads use a statically allocated stack, which is dimensioned according to the corresponding constructor argument.

Genode::Thread

Inter-thread synchronization

Genode provides three inter-thread synchronization primitives, namely Mutex, Blockade, and Semaphore, which model different thread-synchronization situations. Under the hood, they are based on the same low-level Lock primitive, which is visible at the API but not recommended for direct use as it will potentially be removed from the API in a later version.

Genode::Mutex

Example of using a Mutex

 Mutex mutex;
 mutex.acquire();
 mutex.release();

 {
   Mutex::Guard guard(mutex) /* acquire() during construction */
 }                           /* release() on guard object destruction */

 Mutex::Guard guard(mutex);
 mutex.acquire();            /* <-- cause a warning about the deadlock */

Genode::Blockade

Alongside the mutual exclusion of entering critical sections and the startup synchronization of threads, producer-consumer relationships between threads are most common. The Semaphore enables the implementation of this synchronization scheme.

Genode::Semaphore

To synchronize method calls of an object, the Synced_interface can be used to equip the class of the called object with thread safety.

Genode::Synced_interface