Reentrant Function

Definition

A reentrant function is one that can be used by more than one task concurrently without fear of data corruption. Conversely, a non-reentrant function is one that cannot be shared by more than one task unless mutual exclusion to the function is ensured either by using a semaphore or by disabling interrupts during critical sections of code. A reentrant function can be interrupted at any time and resumed at a later time without loss of data. Reentrant functions either use local variables or protect their data when global variables are used.

A reentrant function:
1) Does not hold static data over successive calls
2) Does not return a pointer to static data; all data is provided by the caller of the function
3) Uses local data or ensures protection of global data by making a local copy of it
4) Must not call any non-reentrant functions

Floating Point Reentrant for Keil C51 C compiler

Floating point operations the compiler generates code for (+ - * /) are fully reentrant. But only a few functions in math.h are reentrant.

Those that are not reentrant must be protected from interrupts. One way this can be accomplished is to put a wrapper that disables and re-enables interrupts around the floating point math calls. For example:

#pragma disable        // Disable Interrupts for this function
float ISR_sin (float x)
{
    return (sin(x));
}

Examples

void func(int* x, int* y) 
{ 
    int tmp; 
    tmp=*x; 
    *x=*y; 
    *y=tmp; 
}

the above is reentrant or not?
Reentrant

Non-Reentrant to Reentrant

Non-reentrant version

char* FileName(char *name)
{
    static char fname[13];
    sprintf(fname, "%s", name);       // can't write fname = name
    return fname;
}

Reentrant versions

char* FileName1(char *name, char *fname_buf)      // use thread's own buffer
{
    sprintf(fname_buf, "%s", name);          // can write fname_buf = name
    return fname_buf;
}
char* FileName2(char *name)
{
    char *fname_buf = (char*)malloc(13);       // malloc will allocate memory every call
    sprintf(fname_buf, "%s", name);       // can write fname_buf = name
    return fname_buf;
}

The first one better, because second requires free() to release memory, and takes longer time to allocate memory.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License