What we mean by reentrancy and reentrant function? What is it’s significance in programming? What are the conditions that a function to be reentrant?
Reentrancy is applicable in concurrent programming. Cooperative scheduling need not to consider reentrancy. Prior to discussing on reentrant functions, we need to understand few keywords. Read atomicity and critical section posts.
If one thread tries to change the value of shared data at the same time as another thread tries to read the value, the result is not predictable. We call it as race condition.
A reentrant function guarantees it’s functionality even when the function is invoked (reentered) from concurrent multiple threads. If the function is using variables with static extent, the results will be unpredictable because of race conditions. A library developer need to care in writing reentrant code. Sometimes the bug lies in the library rather than programmer’s code. It is not easy to recreate such bugs during fix.
A Reentrant Function shall satisfy the following conditions,
- Should not call another non-reentrant function
- Should not access static life time variables (static/extern)
- Should not include self modifying code
Thread safety and Reentrant functions
Thread safety and reentrant functions are connected. Every thread safe function is reentrant, but the converse need not be true. A thread safe function can be called from multiple threads even when the function accessing shared data. A thread safe function is guaranteed to serialize accessing any shared data.
An example is string class (C++). Most implementations of string class are reentrant but not thread safe. One can create different instances of string class across multiple threads, but can’t access same instance atomically from multiple threads. For more details of string class see QString.
Reentrancy is key while writing critical sections, signal handlers, interrupt service routines, etc…
Reentrant Function vs Functions with Reentrancy:
The above statement may look strange. There are different memory models of processors. Some architectures use a common set of memory locations to pass arguments to functions. In such case the functions can’t maintain reentrancy when invoked multiple times. Code development for such processors must qualify the function prototype with compiler provided keywords to ensure reentrancy.
Article compiled by Venki. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.