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
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.
沒有留言:
張貼留言