Reentrant functions and non-reentrant functions

Source: Internet
Author: User

Mainly used in a multitasking environment, a reentrant function is simply a function that can be interrupted, that is, it can be interrupted at any moment of execution of the function, go to the OS Scheduler to execute another piece of code, and return control without error, and non-reentrant function because of the use of some system resources, such as the global variable area, interrupt vector table, etc., so if it is interrupted, there may be problems, such functions can not be run in a multi-tasking environment.

It can also be understood that re-entry means that the function can be interrupted, and that the second means that it is not dependent on any environment (including static) other than the variables on its own stack, such that the function is Purecode (pure code) can be re-entered, You can allow multiple copies of the function to run, because they use separate stacks, so they do not interfere with each other. If you do need to access global variables (including static), be aware of implementing mutually exclusive means. Reentrant functions are important in a parallel run environment, but there is a general need to pay some performance cost for accessing global variables.

When you write a reentrant function, if you use a global variable, you should protect it by turning off interrupts, semaphores (that is, p, v operations), and so on.

Description: If the global variable being used is not protected, then this function is not reentrant, that is, when multiple processes call this function, it is likely that the global variable becomes unknowable.

Example: Suppose exam is a global variable of type int, the function squre_exam returns the exam squared value. Then the following function does not have reentrant nature.

unsigned int example (int para)

{

unsigned int temp;
Exam = para; (**)
temp = Square_exam ();
return temp;
}
If this function is called by more than one process, the result may be unknown, because when the (*) statement has just been executed, another process using this function may be just activated, then when the newly activated process executes to this function, the exam will be assigned a different para value, so when the control returns to the "Temp = Square_exam () ", the computed temp is probably not the expected result. This function should be improved as follows.

unsigned int example (int para) {
unsigned int temp;
[Request semaphore operation]//(1)
Exam = para;
temp = Square_exam ();
[Release semaphore operation]
return temp;
}
(1) If the "semaphore" is not applied, it indicates that another process is in the process of assigning a value to exam and calculating its square (that is, the signal is being used), the process must wait for it to release the signal before it can continue execution. If a signal is requested, it can continue, but the other process must wait for the signal to be released by the process before it can be used again.

A method to guarantee the reentrant nature of a function:
When writing a function, try to use local variables (such as registers, variables in the stack), for the global variables to be used to protect (such as the use of closed interrupts, semaphores, etc.), so that the composition of the function must be a reentrant function.
The Reentrant technologies taken in the VxWorks are:
* Dynamic stack variables (each child function has its own independent stack space)
* Protected global variables and static variables
* Task variables


--------------------------------------------------
In the design of real-time systems, multiple tasks often call the same function. If this function is unfortunately designed to be a non-reentrant function, then different tasks calling this function may modify the data of other tasks invoking the function, which can lead to unpredictable consequences. So what is reentrant function? A reentrant function is a process that can be called by multiple tasks, and the task does not have to worry about whether the data will go wrong when it is called. Non-reentrant functions are considered unsafe functions in the design of real-time systems. Most of the functions that meet the following conditions are non-reentrant:
1) The function body uses the static data structure;
2) the malloc () or free () function is called in the function body;
3) The function body calls the standard I/O function.

An example is shown below.
A. reentrant function
void strcpy (char *lpszdest, char *lpszsrc)

{
while (*lpszdest++=*lpszsrc++);
*dest=0;
}

B. Non-reentrant function 1
charctemp;//Global Variables
void SwapChar1 (char *lpcx, char *lpcy)

{
CTEMP=*LPCX;
*lpcx=*lpcy;
lpcy=ctemp;//access to global variables
}

C. Non-reentrant function 2
void SwapChar2 (char *lpcx,char *lpcy)

{
Static char ctemp;//statically local variable
CTEMP=*LPCX;
*lpcx=*lpcy;
lpcy=ctemp;//uses static local variables
}

Question 1, how can I write a reentrant function?
A: In the function body does not access those global variables, do not use static local variables, persist in using only local variables, the written function will be reentrant. If you must access global variables, remember to protect global variables with mutually exclusive semaphores.

Question 2, how can I overwrite a non-reentrant function into a reentrant function?
A: The only way to turn a non-reentrant function into reentrant is to rewrite it with reentrant rules. In fact it is very simple, as long as you follow a few very easy to understand the rules, then the written function is reentrant.
1) Do not use global variables. Because other code is likely to overwrite these variable values.
2) When interacting with hardware, remember to perform operations like Disinterrupt (), which is to turn off hardware interrupts. Complete the interaction remember to open the interrupt, on some series, this is called "Enter/Exit Core".
3) You cannot call any other function that is not reentrant.
4) Use the stack sparingly. It is best to os_enter_kernal first before use.

The stack operation involves memory allocation, and a little inattention can cause data to be overwritten by other tasks, so use the stack with caution! Better not use it! Many hacking programs take advantage of this so that the system can easily gain control of the system by executing illegal code. There are some rules, in short, always remember a word: to ensure that the interruption is safe!

Example problem: Once designed the following function, in the Code view is reminded of a bug, because this function is not reentrant, why?
unsigned int sum_int (unsigned int base)

{
unsigned int index;
static unsigned int sum = 0; Note that the static type
for (index = 1; index <= base; index++)
sum + = index;
return sum;
}

Analysis: So-called functions are reentrant (and can be said to be predictable), that is, the same output should be produced as long as the input data is the same. This function is unpredictable because the static variable is used in the function because of the characteristics of the static variable, which is called a function with the "internal memory" function. So if you need a reentrant function, be sure to avoid using the static variable in the function, the static variable in this function, using the principle that you can not use as much as possible.
Modify the above function to a reentrant function, as long as the static keyword declared in the sum variable is removed, the variable sum becomes a variable of type auto, and the function becomes a reentrant function.
Of course, there are times when a static variable must be used in a function, such as when the return value of a function is a pointer type, the address of a static local variable must be the return value, and if it is the auto type, it is returned as the wrong pointer.

Reentrant functions and non-reentrant functions

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.