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 member function. 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

Locks and semaphores

For mutual exclusive execution of critical sections, there exists a simple lock interface providing lock and unlock semantics. The lock comes in two flavours. Cancelable locks can be unblocked by force via core's cancel-blocking mechanism. In contrast, a non-cancelable lock (Lock) does not reflect the cancellation of its blocking operation at the API level but transparently re-enters its blocking state after a cancellation.

Genode::Cancelable_lock

Genode::Lock

For the use case of using locks for protecting critical sections, the Lock_guard provides a convenient mechanism for the automated unlocking of a lock when leaving a variable scope.

Genode::Lock_guard

Alongside lock-based mutual exclusion of entering critical sections, organizing threads in a producer-consumer relationship is a common design pattern for thread synchronization. The Semaphore interface 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