Semaphores and spin locks | Linux, semaphores, spin locks, sleep locks, spinlocks, semaphore [Post]

Source: Internet
Author: User

To avoid concurrency and prevent competition. The kernel provides a set of Synchronization Methods to protect shared data. Our focus is not to introduce the detailed usage of these methods, but to emphasize the difference between these methods and them.
Linux
The synchronization mechanism used can be said to have been continuously developed and improved since 2.0 to 2.6. From the initial atomic operation to the subsequent semaphores, from the large kernel lock to today's spin lock. Along with the development of these synchronization mechanisms
Linux from single processor to symmetric multi-processor, accompanied by excessive from non-preemptible kernel to preemptible kernel. The locking mechanism becomes more effective and more complex.
Currently, sub-operations in the kernel are mostly used for counting. In other cases, two locks and their variants are most commonly used: one is the spin lock and the other is the semaphore. We will introduce the two lock mechanisms below.

Spin lock
------------------------------------------------------
The spin lock is a kind of lock introduced to prevent multi-processor concurrency. It is widely applied to interrupt processing and other parts in the kernel (for single processor, to prevent the concurrency in the interrupt processing, you can simply disable the interrupt without the need to spin the lock ).
A spin lock can only be held by one kernel task at most. If a kernel task attempts to request a spin lock that has been used (held, then this task will always be busy loop-rotate-Wait for the lock to be available again.
If the lock is not in contention, the kernel task requesting it will immediately get it and continue. The spin lock can prevent more than one kernel task from entering the critical section at any time. Therefore, this lock can effectively avoid competition for shared resources for Kernel Tasks running concurrently on the multi-processor.
In fact, the intention of the spin lock is to implement lightweight locking in a short period of time. A competing spin lock allows the thread requesting it to spin while waiting for the lock to be available again (especially wasting processing time), so the spin lock should not be held for too long. If you need to lock for a long time, it is best to use a semaphore.
The basic form of the spin lock is as follows:
Spin_lock (& mr_lock );
// Critical section
Spin_unlock (& mr_lock );

Because the spin lock can only be held by up to one kernel task at a time point, only one thread is allowed to exist in the critical section at a time point. This satisfies the locking service required by Symmetric Multi-processing machines. On the single processor, the spin lock is only used as a switch to set kernel preemption. If the kernel preemptible does not exist, the spin lock will be completely removed from the kernel during compilation.
To put it simply,The spin lock is mainly used in the kernel to prevent concurrent access to the critical zone in the multi-processor and to prevent competition caused by kernel preemption.In addition, the spin lock does not allow the task to sleep (sleep of a task holding the spin lock will cause an automatic deadlock-Because sleep may cause the kernel task holding the lock to be rescheduled, apply for the lock that you have held again ),It can be used in the interrupt Context.
Deadlock: Assume one or more kernel tasks and one or more resources. Each kernel is waiting for one of these resources, but all resources are occupied. In this case, all kernel tasks are waiting for each other,

But they will never release the occupied resources, so any kernel task cannot obtain the required resources and continue running, which means a deadlock has occurred. Self-occupation means that you possess a certain resource, and then
If you apply for resources that you already possess, it is obviously impossible to obtain the resources again.

Semaphores
------------------------------------------------------
Semaphores in Linux are sleep locks. If a task tries to obtain an held semaphore, the semaphore will push it into the waiting queue and then sleep it. In this case, the processor is free to execute other code. When the process holding the semaphore releases the semaphore, a task in the waiting queue will be awakened to obtain the semaphore.
The sleep feature of semaphores makes the semaphores suitable for cases where the lock is held for a long time. They can only be used in the process context because the interrupt context cannot be scheduled; in addition, when the Code holds a semaphore, it cannot hold a spin lock.

The basic usage of semaphores is as follows:
Static declare_mutex (mr_sem); // declare mutex semaphores
If (down_interruptible (& mr_sem ))
// Interrupted sleep. When the signal arrives, the sleep task is awakened.
// Critical section
Up (& mr_sem );

Differences between semaphores and spin locks
------------------------------------------------------
Although the conditions for use between the two are complex, in fact, in actual use, semaphores and spin locks are not easy to confuse. Note the following principles:
If the code needs to sleep-this often happens when it is synchronized with the user space-using semaphores is the only option. Because it is not restricted by sleep, it is generally easier to use semaphores. If you need
The selection of the lock and semaphore depends on the length of time the lock is held. Ideally, all locks should be held as short as possible, but it is better to use semaphores if the lock is held for a long time.
Select. In addition, unlike the spin lock, semaphores do not disable kernel preemption, so the code holding semaphores can be preemptible. This means that the semaphore will not have a negative impact on the scheduling response time.

Semaphores
------------------------------------------------------
Recommended locking method

The spin lock is preferred for low-cost locking.
Short-term locks give priority to spin locks
Semaphores are preferentially used for long-term locking.
Apply spin lock to intercept context locking
Holding locks requires sleep and scheduling to use semaphores.

Source of the following parts: kcrazy paper

I understand the spin lock.

Small A, Small B, small C, and small d share the same room, but the room only has a Mouch and a toilet. When they want to "just", they will lock the door of the Mouch and occupy the toilet. For example, John is occupying the toilet, so they are very comfortable. It happened that John was in a hurry, but he couldn't help it because John had locked the door. As a result, Mr. B is in a hurry at the door, that is, "Spin ". Note that the word "Spin" is well used. Tom goes back to bed instead of locking the door, but "Spin" at the door ".... The final result is that A is unlocked and B is occupied. In addition, the action in the locking process is neat and neat, so that no one else can compete in front of the lock.

This is a recurring process ......

Here the small a, B, c, d is the processor, and the moufang lock is the spin lock. When other processors want to access this public resource, they must first obtain the lock. If the lock is occupied, the spin (loop) waits.

John's concentration indicates that IRQL is 2, and switch locks quickly indicate atomic operations.

----------------------------------------------------------

I don't know if I understand it correctly or not. Some examples may be inappropriate. If you have any misunderstanding, you may wish to give us some advice to avoid going astray and regret it.

----------------------------------------------------------

I wrote a test program and tested it:

Kspin_lock spinlock;

Ntstatus DriverEntry (
In pdriver_object driverobject,
In punicode_string registrypath
)
{
Ntstatus status;
Unicode_string devicename;
Pdevice_object deviceobject;
Handle threadhandle;
Kirql oldirql;
Kirql IRQL;
Ulong processor;
Ulong I;

Deviceobject = NULL;

Rtlinitunicodestring (& devicename, devicenamebuffer );

Status = iocreatedevice (driverobject,
0,
& Devicename,
File_device_unknown,
0,
False,
& Deviceobject );
If (! Nt_success (Status ))
{
Return status;
}

Driverobject-> driverunload = driverunload;

Keinitializespinlock (& spinlock); // (2)

Pscreatesystemthread (& threadhandle, thread_all_access, null, null, threadroutine, null );

I = 10000;

Keacquirespinlock (& spinlock, & oldirql );

While (I --)
{
_ ASM NOP
IRQL = kegetcurrentirql ();
Processor = kegetcurrentprocessornumber ();
Kdprint ("[% d] currentirql: \ t % d", processor, IRQL ));
}

Kereleasespinlock (& spinlock, oldirql );

Return status;
}

Void
Threadroutine (in pvoid startcontext)
{
Kirql oldirql;
Kirql IRQL;
Ulong processor;
Ulong I;

I = 10000;

Keacquirespinlock (& spinlock, & oldirql); // (1)

While (I --)
{
_ ASM NOP
IRQL = kegetcurrentirql ();
Processor = kegetcurrentprocessornumber ();

Kdprint ("** [% d] currentirql: \ t % d", processor, IRQL ));
}

Kereleasespinlock (& spinlock, oldirql); // (1)
}

---------------------------------------------------------------------------------

First, I am a dual-core system. If it is a single core, I want to enter the spin lock and IRQL has been raised to the DPC level, and the second thread will not be able to run. If he runs unexpectedly, a deadlock will occur.

Test in several cases:

1. Test the code above.

First catch the lock first, then catch the lock and then run. And IRQL during the lock is at the DPC level.

2. Remove the two rows marked with (1)

The result is that two threads run simultaneously. one processor occupies [0] and the other processor occupies [1].

The locked IRQL level is DPC level.

The unlocked IRQL value is 0.

That is, the spin lock does not affect the normal operation of other processors. Unless Other Processors also want to obtain the lock.

3. Remove the line marked (2) (the spinlock is a global variable)

The result is the same as that of 1, because the global variable is initialized to 0 by default.

Related Article

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.