Three critical zone management mechanisms in UCOS

Source: Internet
Author: User

Anyone familiar with UCOS, or who has read UCOS books written by Jean. J. labrosse, will surely know the famous critical management Macros in UCOS: OS _enter_critical () and OS _exit_critical ().

The critical section is also protected through Guanzhong disconnection. OS _enter_critical/OS _exit_critical implements three methods in total, as shown below:

 
# If OS _critical_method = 1 # define OS _enter_critical () _ ASM _ ("CLI") # define OS _exit_critical () _ ASM _ ("Sti ") # endif # If OS _critical_method = 2 # define OS _enter_critical () _ ASM _ ("pushf \ n \ t CLI") # define OS _exit_critical () _ ASM _ ("popf") # endif # If OS _critical_method = 3 # define OS _enter_critical () (cpu_sr = oscpusavesr () # define OS _exit_critical () (oscpurestoresr (cpu_sr) # endif

In the first method, OS _enter_critical () is simply disconnected, and OS _exit_critical () is simply interrupted. This method is simple and efficient, but it cannot meet the nested conditions. If there is two-layer critical zone protection, it will interrupt when exiting the inner critical zone, and the outer critical zone will also lose protection. Although the UCOS kernel is well written, there is no obvious nesting of critical zones, but no one can guarantee that there is no such thing. It cannot guarantee that there will be no such thing in the future and that there will be no additional driver or location, so basically, the first method is useless.

In the second method, OS _enter_critical () saves the previous flag register content to the stack before the disconnection, and OS _exit_critical () restores the previously saved status from the stack. In this way, the nesting of the critical section is allowed. However, it seems that this method still has many problems and even has a fatal vulnerability.

When OS _critical_method = 2, assume that the followingCode:

 
Function_a () {int A = (1 <31); OS _enter_critical (); function_ B (a); OS _exit_critical ();}

What will happen? In my experiment, a processor exception occurs after OS _exit_critical. Why is there an exception? Let me simulate its assembly code. The reason for simulation is not that I make up data, but that the functions I encounter are more complex and need more code to understand. This problem is universal, so please allow me to reveal this hidden bug.

 
Function_a: Push EBP mov EBP, esp sub ESP, 8 mov 4 (ESP), 0x80000000 pushfd CLI mov EDI, 4 (ESP) mov (ESP ), EDI call function_ B popfd mov ESP, EBP RET

This is a compilation Simulation Based on the GCC compilation results, whether or not the optimization option is added. The cause of this problem is very simple. GCC wants to be smart. It can downgrade the stack at a time, and then it can place parameters on the stack to call other functions at will. This method is more meaningful, especially when many functions are called. Moreover, the intelligence of GCC does not seem to have much to do with the optimization option O, as if there is nothing to prohibit it from doing so. But the problem is that GCC does not know that our OS _enter_critical () and OS _exit_critical () operate the stack. I tried to use _ ASM _ volatile _ ("pushfd
\ N \ tcli ":" Memory ") to notify GCC that the memory data has changed, but apparently GCC does not think the stack has changed. Therefore, the status of OS _enter_critical () stored on the stack is washed out, for example, the value of parameter A is called here. It depends on luck to determine whether or not an exception will be thrown during recovery. But I believe that a person's luck will not always be so good, so do not use OS _critical_method = 2 in the end.

Third, use local variables to save the interruption status before the disconnection. This is also a common choice for almost all real-time operating systems. However, UCOS is an amazing solution. to be compatible with the first two methods, the OS _enter_critical ()/OS _exit_critical () macro definition does not provide the function of passing status parameters. Therefore, its critical removal must be used as follows:

 
Function_a () {# if OS _critical_method = 3 int cpu_sr; # endif int A = 1 <31; OS _enter_critical (); function_ B (a); OS _exit_critical ();}

This kind of code is awkward, probably because a macro definition is added to the function. Then, the third method cannot support the nested critical section of the same function, which may cause some problems when used in some very long functions.

Well, if there is a problem, there must be a solution. After all, I am not trying to make everyone lose confidence in UCOS. We can refer to how the common real-time operating system implements the Guanzhong critical section, that is, saving the interrupt status with local variables explicitly.

 
Int int_lock () {int cpu_sr; _ ASM _ volatile _ ("pushfd \ n \ t pop % 0 \ n \ t CLI ": "= r" (cpu_sr); Return cpu_sr;} void int_unlock (INT cpu_sr) {_ ASM _ volatile _ ("Push % 0 \ n \ t popfd": "R" (cpu_sr);} function_a () {int, cpu_sr; A = 1 <31; cpu_sr = int_lock (); function_ B (a); int_unlock (cpu_sr );}

Int_lock () and int_unlock () can be implemented more efficiently by means of assembly, or you can choose to restore the status of the interrupt flag only. This method allows us to display the management status, and I think it is at least clearer than macro definition.

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.