Non-modifiable procedures are called Reentrant procedures.
A function or subroutine is said to be reentrant if it can be interrupted in the middle of its execution, then safely called again (“re-entered”) before its previous invocations complete execution.
The interruption could be caused by an internal action such as a jump or call, or by an external action such as an interrupt or signal.
Reentrant functions are used in applications like hardware interrupt handling, recursion, etc. They have to satisfy certain conditions to be called as reentrant:
- They may not use global and static data.
- They should not modify their own code.
- They should not call another non-reentrant function.
Following example will clear the above statements:
Recursive Non reenterant function:int i;
int nonReentrantRecursive(int n) {
if(n == 0) {
i = 1;
return 1;
} else {
i = n * nonReentrantRecursive(n - 1);
return i;
}
}
The above program uses global variable $i$, which stores the intermediate results of the program.
Thus, when this recursive program is interrupted, it will restart from the new, overwritten value of $i$.
Recursive Reenterant function:
int reentrantRecursive(int n, int i) {
if(n == 0) {
return i * 1;
} else {
return reentrantRecursive(n - 1, i * n);
}
}
In this version of the function, $i$ is no longer a global variable. Instead, it’s passed as a parameter to the function. This ensures that each invocation of the function has its own copy of $i$, so the function is now reentrant.