Reentrant Function

A function is said to be reentrant if there is a provision to interrupt the function in the course of execution, service the interrupt service routine and then resume the earlier going on function, without hampering its earlier course of action. Reentrant functions are used in applications like hardware interrupt handling, recursion, etc.

 
The function has to satisfy certain conditions to be called as reentrant:
1. It may not use global and static data. Though there are no restrictions, but it is generally not advised. because the interrupt may change certain global values and resuming the course of action of the reentrant function with the new data may give undesired results.

 
2. It should not modify is own code. This is important because the course of action of the function should remain the same throughout the code. But, this may be allowed in case the interrupt routine uses a local copy of the reentrant function every time it uses different values or before and after the interrupt.
 
3. Should not call another non-reentrant function.

Thread safety and Reentrant functions
Reentrancy is distinct from, but closely related to, thread-safety. A function can be thread-safe and still not reentrant. For example, a function could be wrapped all around with a mutex (which avoids problems in multithreading environments), but if that function is used in an interrupt service routine, it could starve waiting for the first execution to release the mutex. The key for avoiding confusion is that reentrant refers to only one thread executing. It is a concept from the time when no multitasking operating systems existed. (Source : https://en.wikipedia.org/wiki/Reentrancy_(computing))

 
Example of Non-Reentrant Functions:

// A non-reentrant example [The function depends on
// global variable i]

int i;

// Both fun1() and fun2() are not reentrant

// fun1() is NOT reentrant because it uses global variable i
int fun1()
{
    return i * 5;
}

// fun2() is NOT reentrant because it calls a non-reentrant
// function
int fun2()
{
   return fun1() * 5;
}

Example of Reentrant Functions:
In the below code, fun2 is a reentrant function. If an interrupt that pauses its execution and shifts the control to fun1. After fun1 completes, the control is again transferred to fun2 and it reenters the execution phase.

// Both fun1() and fun2() are not reentrant
int fun1(int i)
{
    return i * 5;
}

int fun2(int i)
{
   return fun1() * 5;
}

 

Article compiled by Venki. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.







Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the link here.

  • Vasant

    I came to this article to get more clarity on the concept after reading articles about this on other forums..The following statement is WRONG.”Every thread safe function is reentrant, but the converse need not be true.” I stopped reading the article here itself.

  • da3m0n
  • dwaijam

    This article should be taken down as it might teach wrong things to a new enthusiast

    • Kartik

      Could you specify what concepts are wrong in the article?

  • Someone

    “Reentrancy is applicable in concurrent programming. Cooperative scheduling need not to consider reentrancy.” – This is completely wrong! “Every thread safe function is reentrant” – this is completely wrong too! You don’t seem to understand the concept of reentrant functions yourself. You could at least have read the wikipedia page about reentrancy before writing such a misleading article.

  • Sreekanth Muralidharan

    To make it simple. Think of a C library function printf. When printf accesses your terminal to print the characters. Now say, process A runs a printf statement and it reached line 5 of printf function.(line 5 in source of printf in C library). Now consider that another process, B issues a printf at the time when A reached line 5. The context for printf for B should be from line 1, NOT from line 5. This is the case of a reentrant function, which maintains its state of execution, in multiple processes or thread. Correct me, if anything went wrong here.

  • Liviu

    Here is an example of a function that is thread-safe and not reentrant, thus not every thread-safe function is also re-entrant.
    See also discussion.

  • shashank

    A subroutine that is directly or indirectly recursive should be reentrant..why plz exsplain

    • Venki

      @shashank, the question is not clear to me. Are you considering assembly programming? A subroutine (function) should be reentrant when invoked by concurrent threads, irrespective of recursive or not.

      If it from assembly perspective, the programmer would need to take care of saving argument registers (based on processor architecture) on every recursive invocation of the routine.

      Let me know if I am missing to learn something.

  • @Shekhu, I don’t think any relation between reentrant function and recursive function. Reentrant function deals about data consistency across multiple threads where as recursion is design technique.

    Reentrant function builds on stack of thread. If we are sure that recursive function is reentrant, it can be called by multiple threads, since each thread will have its own stack.

  • Shekhu

    Is there any relation between reenterant and recursive functions?