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.
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.
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 */
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.
To synchronize method calls of an object, the Synced_interface can be used to equip the class of the called object with thread safety.