Spin lock Spin_lock and Raw_spin_lock

Source: Internet
Author: User

spin lock Spin_lock and Raw_spin_lock

http://blog.csdn.net/droidphone/article/details/7395983

This article does not intend to explore in detail the detailed implementation mechanism of Spin_lock, but the recent emergence of Raw_spin_lock more troubled, do not know when to use Spin_lock, when with Raw_spin_lock, so there is this article.


/*****************************************************************************************************/
Statement: The content of this blog by Http://blog.csdn.net/droidphone Original, reproduced please indicate the source, thank you!
/*****************************************************************************************************/

1. Critical area (Critical section) we know that a critical section is a code interval in which some shared data objects need to be accessed, or buses, hardware registers, and so on, usually the range of this code interval is controlled in the smallest possible range. Access to these data objects and hardware objects needs to be protected within the critical area, ensuring that the objects are not modified by code outside the critical section before exiting the critical section. We need to use a critical section for protection when there are several situations:
    • (1) In a system that can be preempted (preemption), two threads simultaneously access the same object;
    • (2) Threads and interrupts simultaneously access the same object;
    • (3) in multi-core systems (SMP), it is possible that two CPUs may access the same object at the same time;
2. Spin Lock (Spin_lock) for a single processor system, in the first case, we can use the following methods as long as the system preemption is temporarily turned off: [CPP]View Plaincopy
    1. Preempt_disable ();
    2. .....
    3. Code to access the shared object
    4. ......
    5. Preempt_enable ();

Similarly, for a single-processor system, in the second case, we can use the following methods as long as the interrupt is temporarily closed:

[CPP]View Plaincopy
    1. Local_irq_disable ();
    2. ......
    3. Code to access the shared object
    4. ......
    5. Local_irq_enable ();

So, for multi-processor systems, is the above method still true? The answer is clear: not set up.

In the first case, although preemption is forbidden, but the other CPU is still running on the thread, the code snippet above is obviously powerless if it is just going to access the shared object.

In the second case, although the interruption of the local CPU is disabled, another CPU can still generate interrupts, and if his interrupt service program is just about to access the shared object, the same code snippet cannot protect the shared object.

In fact, in Linux, three of the above-mentioned situations can be solved with a spin lock (Spin_lock). The basic spin-lock function pairs are:
    • Spin_lock (spinlock_t *lock);
    • Spin_unlock (spinlock_t *lock);
For a single-processor system, when the debug option is not turned on, spinlock_t is actually an empty structure, after the above two functions are expanded, actually just call preempt_disable () and preempt_enable (), for a single processor system, when the preemption is switched off, Other threads cannot be scheduled to run, so there is no need to do extra work, unless the interrupt arrives, but the kernel provides additional variant functions to handle the problem of interrupts.
For multiprocessor systems, spinlock_t is actually equivalent to an integer in the memory unit, and the kernel guarantees that the Spin_lock series function atomically operates on the integer, except that calling Preempt_disable () and preempt_enable () prevents the thread from being preempted , the spinlock_t must also be locked so that if another CPU's code is to use the critical section object, it must spin-wait.
For objects to be accessed by interrupts and normal threads, the kernel provides two additional sets of variant functions:
    • SPIN_LOCK_IRQ (spinlock_t *lock);
    • SPIN_UNLOCK_IRQ (spinlock_t *lock);
And:
    • Spin_lock_irqsave (lock, flags);
    • Spin_lock_irqrestore (lock, flags);
We can use the above three pair of variant functions (macros) as follows:
    • Use Spin_lock ()/spin_unlock () If you are only accessing shared objects between normal threads at the same time;
    • If the shared object is accessed at the same time between the interrupt and the normal thread, and is sure to open the interrupt after exiting the critical section, use SPIN_LOCK_IRQ ()/spin_unlock_irq ();
    • Use Spin_lock_irqsave ()/spin_unlock_irqrestore () If the shared object is accessed at the same time between the interrupt and the normal thread, and you want to remain interrupted after exiting the critical section;
In fact, the variant is not only these few, there are read_lock_xxx/write_lock_xxx, SPIN_LOCK_BH/SPIN_UNLOCK_BH, spin_trylock_xxx and so on. But the usual is the above several. 3. Raw_spin_lock after the 2.6.33 version, the kernel added the Raw_spin_lock series, using the same method as the Spin_lock series, except that the parameters spinlock_t into raw_spinlock_t. And in the mainline version of the kernel, the Spin_lock series simply calls the functions of the Raw_spin_lock series, but the kernel code is where Spin_lock is used, and raw_spin_lock is used in some places. Isn't it weird? To answer this question, we're going back to 2004, MontaVista Software, Inc. 's developers put forward a real-time Linux kernel model in the mailing list, designed to improve the real-time nature of Linux, and then Ingo Molnar quickly implemented the model in one of his projects and eventually produced a patch for real-time preemption. The model allows for preemption in the critical section, and the operation of the application critical section can cause the process to hibernate, which will cause the spin lock mechanism to be modified and changed from the original integer atomic operation to the semaphore operation. At that time there were about 10000 in the kernel using the spin lock code, the direct modification of the spin_lock will cause the patch is too large, so they decided to modify only what really does not allow preemption and hibernation, and these places only 100, these places to use Raw_spin _lock, however, because the original kernel already has raw_spin_lock this name space, used to represent the implementation of system-related atomic operations, so Linus I suggest:
    • Change the original raw_spin_lock to Arch_spin_lock;
    • Change the original spin_lock to Raw_spin_lock;
    • To achieve a new spin_lock;
I don't know if you know that. for 2.6.33 and later versions, my understanding is:
    • Use spin_lock whenever possible;
    • Absolutely not allowed to be preempted and dormant where, use Raw_spin_lock, otherwise use spin_lock;
    • If your critical area is small enough, use raw_spin_lock;
for systems that do not have patches on linux-rt (real-time Linux), Spin_lock simply calls Raw_spin_lock, in fact they are exactly the same, and if this patch is called, Spin_ Lock uses semaphores to complete protection of critical areas, the benefit is that the same CPU can have multiple critical sections at the same time, and the original system because of the reason for the prohibition of preemption, once entered the critical section, the other critical section will not be able to operate, the new system in the same critical section allows other processes to hibernate wait, rather than seize the CPU spin operation. Write this article, the kernel version is already 3.3, the main version has not merged linux-rt content, perhaps one day will be merged in, and for your code can be compatible with LINUX-RT, it is best to adhere to the above three principles.

Spin lock Spin_lock and Raw_spin_lock

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.