Reentrancy (computing)

Reentrancy is a programming concept where a function or subroutine can be interrupted and then resumed before it finishes executing.

Reentrant code is designed to be safe and predictable when multiple instances of the same function are called simultaneously or in quick succession.

A computer program or subroutine is called reentrant if multiple invocations can safely run concurrently on multiple processors, or if on a single-processor system its execution can be interrupted and a new execution of it can be safely started (it can be "re-entered").

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, unlike recursion where new invocations can only be caused by internal call.

Hence, interrupt service routines are limited in the actions they can perform; for instance, they are usually restricted from accessing the file system and sometimes even from allocating memory.

For example, a function could be wrapped all around with a mutex (which avoids problems in multithreading environments), but, if that function were used in an interrupt service routine, it could starve waiting for the first execution to release the mutex.

For example, if the subroutine modifies a 64-bit global variable on a 32-bit machine, the operation may be split into two 32-bit operations, and thus, if the subroutine is interrupted while executing, and called again from the interrupt handler, the global variable may be in a state where only 32 bits have been updated.

The programming language might provide atomicity guarantees for interruption caused by an internal action such as a jump or call.

Then the function f in an expression like (global:=1) + (f()), where the order of evaluation of the subexpressions might be arbitrary in a programming language, would see the global variable either set to 1 or to its previous value, but not in an intermediate state where only part has been updated.

As such, it should not have been used in the interrupt service routine isr(): The function swap() in the preceding example can be made thread-safe by making tmp thread-local.

It still fails to be reentrant, and this will continue to cause problems if isr() is called in the same context as a thread already executing swap(): An implementation of swap() that allocates tmp on the stack instead of globally and that is called only with unshared variables as parameters[b] is both thread-safe and reentrant.