Reentrant and non-reentrant functions __ Functions

Source: Internet
Author: User
Tags semaphore

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

It can also be understood that reentry means repeated entry, first meaning that the function can be interrupted, and second, that it does not rely on any environment (including static) other than the variables on its own stack, so that the function is Purecode (pure code) can be reentrant, Multiple copies of the function can be allowed to run because they are using separate stacks, so they don't interfere with each other. If you do need to access global variables (including static), be careful to implement mutexes. Reentrant functions are important in parallel running environments, but typically pay a performance price for accessing global variables.

When writing reentrant functions, if global variables are used, they should be protected by means of turn-off interrupts, semaphores (i.e., p, v operations).

Note: If you do not protect the global variable you are using, this function is not reentrant, that is, when multiple processes call this function, it is very likely that the global variable becomes unknowable.

Example: Assuming exam is an int-type global variable, the function Squre_exam returns the exam squared value. Then the following function does not have a reentrant nature.

unsigned int example (int para)

{

unsigned int temp;
Exam = para; (**)
temp = Square_exam ();
return temp;
}
If this function is invoked by multiple processes, the result may be unknown, because another process that uses this function may just be activated when the (* * *) statement is finished, then when the newly activated process executes to this function, the exam is 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;
[Application for semaphore operation]//(1)
Exam = para;
temp = Square_exam ();
[Release semaphore operation]
return temp;
}
(1) If a "semaphore" is not applied, stating that another process is in the process of assigning value to exam and calculating its square (that is, using this signal), this process must wait for it to release the signal before it can proceed. If you apply for a signal, you can continue, but the other process must wait for this process to release the semaphore before using this signal again.

Ways to ensure the reentrant nature of a function:
When writing functions to use local variables (such as registers, variables in the stack), for the global variables to be used to be protected (such as taking off interrupts, semaphores and other methods), so that the composition of the function must be a reentrant function.
The Reentrant technologies adopted in VxWorks are:
* Dynamic stack variable (each child function has its own separate stack space)
* Protected global variables and static variables
* Task variables


--------------------------------------------------
In the design of real-time systems, multiple tasks often invoke the same function. If this function is unfortunately designed to be a function that cannot be reentrant, then different tasks calling this function may modify other tasks to call the function's data, causing unpredictable consequences. So what is a reentrant function? A reentrant function is a procedure that can be invoked by multiple tasks, and the task does not have to worry about whether the data will go wrong when 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 not reentrant:
1 The static data structure is used in the function body;
2 The function body calls the malloc () or free () function;
3 The standard I/O function is called in the function body.

The following examples illustrate.
A. reentrant functions
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 a static local variable
}

Question 1, how can I write a reentrant function.
A: Do not access those global variables in the function body, do not use static local variables, adhere to the use of only local variables, the written function will be reentrant. If you have to access global variables, remember to protect the global variables with mutually exclusive semaphores.

Question 2, how to rewrite a function that cannot be reentrant into a reentrant function.
A: The only way to turn a non reentrant function into reentrant is to override it with a reentrant rule. It's very simple, as long as you follow a few rules that are easy to understand, the functions you write are reentrant.
1 Do not use global variables. Because other code is likely to overwrite these variable values.
2 when interacting with the hardware, remember to perform such actions as Disinterrupt (), that is, to turn off the hardware interrupt. Complete the interaction remember to turn on interrupts, in some series, this is called "Enter/Exit Core".
3 cannot call any other functions that cannot be reentrant.
4 Use the stack carefully. It is best to os_enter_kernal first before using.

Stack operations involve memory allocations, and a little inattention can result in the benefit of overwriting data on other tasks, so use the stack with caution. It's best not to use it. Many hacker programs take advantage of this so that the system can execute illegal code to gain control of the system easily. There are some rules, in short, always remember a word: to ensure that the interruption is safe.

Instance problem: The following function has been designed to be alerted to bugs in the Code view because the function is not reentrant and why.
unsigned int sum_int (unsigned int base)

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

    Analysis: The so-called function is reentrant (or 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, such functions are called: Functions with "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 the function, and use the principle that you don't have to do it as much as possible.
    modifies the above function to a reentrant function, as long as the static keyword in the declaring sum variable is removed and the sum of variables becomes a variable of type auto, and the function becomes a reentrant function.
    Of course, there are times when you have to use a static variable in a function, such as when a function's return value is a pointer type, it must be the address of a static local variable as the return value and, if it is the auto type, return to the wrong pointer.

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.