C-reentrant function && non-reentrant function

Source: Internet
Author: User

reentrant functions


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? Reentrant refers to 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) A static data structure is used in the function body;

(2) the malloc () or free () function is called in the function body;

(3) The function body calls the standard I/O function.


How can I write a reentrant function? In the function body does not access those global variables, do not use static local variables, persist in using only the default state (auto) Local variables, the written function will be reentrant. If you must access global variables, remember to protect global variables with mutually exclusive semaphores. or call the function before the shutdown interrupt, call and then open the interrupt.

Reentrant functions can be called by more than one task without worrying about data corruption. Reentrant functions can be interrupted at any time, and can be run after a period of time, while the corresponding data is not lost. You can re-enter the function or use only local variables, either in the CPU registers or on the stack, or with global variables, to protect the global variables.

Myth 2:


A reentrant function is simply: a function that can be interrupted. That is, you can break his run at any time the function executes, and execute another piece of code without any errors when the task is scheduled. The non-reentrant function is not able to run in a multitasking environment because it uses some system resources, such as the global variable area, the interrupt vector table, and so on, so that if he is interrupted, there may be a problem.

Basically the following function is non-reentrant
(1) A static data structure is used in the function body;
(2) the malloc () or free () function is called in the function body;
(3) The function body calls the standard I/O function.

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.

First, do not use global variables. Because other code is likely to overwrite these variable values.

Second, 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, in some series, this is called "Enter/exit core" or use os_enter_kernal/os_exit_kernal to describe. This is critical zone protection.

Third, you cannot call any function that is not reentrant.

IV, use the stack with caution. It is best to os_enter_kernal first before use.

There are some rules that are well understood, in short, always remember a word: to ensure that the interruption is safe!

I believe a lot of people have read the following question.

Interrupts are an important part of an embedded system, which leads to a lot of compiler developers providing an extension-to let standard C support interrupts. The fact that it is represented is that a new keyword __interrupt has been produced. The following code uses the __interrupt keyword to define an interrupt service subroutine (ISR), please comment on this code.

__interrupt Double Compute_area (double radius)
{
Double area = PI * radius * RADIUS;
printf ("\narea =%f", area);
return area;
}

There are so many mistakes in this function that you don't know where to start:
1) The ISR cannot return a value. If you do not understand this, then you will not be employed.
2) The ISR cannot pass parameters. If you do not see this, your chances of being employed are equal to the first item.
3) In many processors/compilers, floating-point is generally non-reentrant. Some processors/compilers require the register to be placed in the stack, and some processors/compilers do not allow floating-point operations in the ISR. In addition, the ISR should be short and efficient, and it is unwise to do floating-point operations in the ISR.
4) with the 3rd same strain, printf () often has re-entryand performance problems. If you lose the third and 4th, I will not be too difficult for you.  Needless to say, if you can get the post two o'clock, then your employment prospects are getting brighter. -And if the interrupt service has a return value, whose value is returned to?
In the operation of the system, must be some kind of interrupt source set off the corresponding interruption, the system hangs on the interrupt service program on-site processing, such as alarm operations, and then clear the interruption.
That is, the interrupt service program is linked to a class of interrupt sources, and the generation of these interrupt sources is random, so the interrupt service program does not have a fixed caller, and there is no fixed return address, so the return value is not used

My problem is that printf (), which is referred to here, often has a problem of re-entry, specifically what does it mean? Can someone explain it to you? This concept in the embedded operating system is important, due to the existence of task scheduling, its real-time system, the disenfranchised kernel is dangerous, like a quiet mine. may be triggered or may be safe and sound. Due to the unpredictable nature of its running results, the system will be a hidden danger.

Here is a quote from someone else's explanation:

This is primarily used in multitasking environments, where a reentrant function is simply: a function that can be interrupted. That is, you can interrupt the operation at any time during the execution of the function, and execute another piece of code without error on the OS schedule. The non-reentrant function is not able to run in a multitasking environment because it uses some system resources, such as the global variable area, the interrupt vector table, and so on, so that if he is interrupted, there may be a problem.

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.

First, do not use global variables. Because other code is likely to overwrite these variable values.

Second, 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, in some series, this is called "Enter/exit core" or use os_enter_kernal/os_exit_kernal to describe.

Third, you cannot call any function that is not reentrant.

IV, use the stack with caution. It is best to os_enter_kernal first before use.

There are some rules that are well understood, in short, always remember a word: to ensure that the interruption is safe!

In layman's terms: Because interrupts are likely to occur at any time, the breakpoint location is not expected. Therefore, it is important to ensure that each function has a stability that does not interrupt, pushes the stack, turns to the ISR, and continues to perform the impact after the stack. This means having the ability to be unaffected by interruptions. With this requirement, each function that you provide and write cannot be used by public resources or variables, because the ISR (Interrupt service program) can be used to modify or acquire the resource, which may cause the outage to be returned, and this common resource is beyond recognition.


Most of the functions that meet the following conditions are non-reentrant:

(1) A static data structure is used in the function body;

(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.

reentrant functions

void strcpy (char* lpszdest, char* lpszsrc)

{

while (*lpszdest++ = *lpszsrc++);

*dest=0;

}

Non-reentrant function 1

Char ctemp; Global variables

void SwapChar1 (char* lpcx, char* lpcy)

{

Ctemp = *LPCX;

*LPCX = *lpcy;

Lpcy = ctemp; Access to global variables, which can cause problems in multiple threads that share memory

}

Non-reentrant function 2

void SwapChar2 (char* lpcx, char* lpcy)

{

static char ctemp; Static local Variables

Ctemp = *LPCX;

*LPCX = *lpcy;

Lpcy = ctemp; Static local variables are used, which can cause problems in multiple threads that share memory

}

How can I write a reentrant function? 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.

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.