concurrency control in Linux drivers

Source: Internet
Author: User
Tags mutex semaphore volatile

Modern operating systems have three main features: interrupt processing, multitasking, and multiprocessor. These attributes cause errors that may occur when multiple processes, threads, or CPUs are accessing a resource at the same time, and these errors are not allowed by the operating system. In the operating system, the kernel needs to provide a concurrency control mechanism, for shared resources for Protection

In the operating system, concurrency refers to a time period in which several programs are running from the start to completion, and these programs run on the same processor, but only one program runs on the processor at any one point. Concurrency can easily lead to competition issues. Competition is the simultaneous access of two or more processes to a resource at the same time, causing a resource error. The concurrency control mechanism has the following types:

1. Atomic variable operation:Atomic variable operations (divided into atomic integer operations and atomic bit operations) are never interrupted by any other task or time until the execution is complete.not half done .,To execute other code. Atomic operation requiresto support the hardware, so it is schema-related, and its API and atomic type definitions are in include/asm/atomic.h, and are implemented using assembly language. In Linux, the atomic variables are defined as follows: typedefstruct{
volatileintCounter
} atomic_t;

The keyword volatile is used to imply that GCC does not optimize data for this type, so access to this variable counte is memory-based and not buffered into registers. stored in the register may result in in-memory data being changed, while the data in which it is hosted does not change.

(1) Atomic integral type operation:

1)definitionatomic_t variables:#defineAtomic_init (i) ((atomic_t) {(i)})

atomic_t v = atomic_init (0); Defines the atomic variable V and initializes it to 0

2)SetThe value of the atomic variable#defineAtomic_set (V,i) ((v)->counter = (i))
voidAtomic_set (atomic_t *v,inti);//set the value of the atomic variable to I3)GetThe value of the atomic variable:#defineAtomic_read (v) ((v)->counter + 0)
Atomic_read (atomic_t *v);//returns the value of an atomic variable

4) Atomic variables Add/Subtract:

Static__inline__voidAtomic_add (intI, atomic_t * v);//atomic variable Increase I
Static__inline__voidAtomic_sub (intI, atomic_t * v);//Atomic variable Reduction i

5) Atomic variables self-increment/self-subtraction:

#defineAtomic_inc (v) atomic_add (1, v);//atom variable plus 1
#defineAtomic_dec (v) atomic_sub (1, v);//atomic variable minus 1

6) Operation and test:

//These operations perform a self-increment, decrement, minus operation on an atomic variable after the test is 0, which returns true, otherwise false
#defineAtomic_inc_and_test (v) (Atomic_add_return (1, (v)) = = 0)
StaticInlineintAtomic_add_return (intI, atomic_t *v)

(2) Atomic bit operation (operates individually according to each bit of the data):

StaticInlinevoidSet_bit (NR,void*ADDR);//set the NR bit of the addr address, the so-called set bit is about to write 1
StaticInlinevoidClear_bit (NR,void*ADDR);//clears the NR bit of the addr address, and the so-called clear bit is about to write 0
StaticInlinevoidChange_bit (NR,void*ADDR);
StaticInlinevoidTest_bit (NR,void*ADDR);
StaticInlineintTest_and_set_bit (NR,void*ADDR);
StaticInlineintTest_and_clear_bit (NR,void*ADDR);
Staticinlineinttest_and_change_bit (NR,void*addr);The advantages of atomic manipulation are simple to write, the disadvantage is that the function is too simple, can only do the counting operation, the protection of too few things.

2. Spin lockSpin locks are designed to prevent multi-processor concurrencyAnd the introduction of a lock, it should be for interrupt handlingand other parts.  For a single processor, the prevention of concurrency in interrupt processing can be simplified by turning off interrupts without the need for a spin lock. A spin lock can only be held by a single kernel task, and if a kernel task attempts to request a spin lock that has been contended (already held), the task will keep busy looping all the time--rotation--waits for the lock to be re-usable. If the lock is not contended, the kernel task requesting it can get it immediately and continue. A spin lock can prevent more than one kernel task from entering the critical section at any time, so this lock effectively avoids competing for shared resources on multi-processor kernel tasks that run concurrently. (1)use of spin lock:spinlock_t spin;//Defining spin Locks
Spin_lock_init (Lock);//Initialize spin lock
Spin_lock (Lock);//A successful spin lock is returned immediately, otherwise the spin is there until the hold of the spin lock is released
Spin_trylock (Lock);//a successful spin lock returns true immediately, otherwise it returns false instead of "spinning in place" as in the previous
Spin_unlock (Lock);//Release spin lockUsage Code: spinlock_tLock;
Spin_lock_init (&Lock);
Spin_lock (&Lock);
....//Critical Resource Area
Spin_unlock (&Lock);

(2) Precautions:

1) Spin lock is a kind of busy waiting. It is a suitable short timeLocked in LightweightLocking mechanism. 2) Spin lock cannot be used recursively。 Spin locks are designed to synchronize between different threads or functions. This is because if a thread is in a busy wait state when it already holds a spin lock, it has no chance of releasing its own lock. If you call yourself again at this point, the spin lock will never have an opportunity to execute.

3. Signal VolumeIn Linux, two semaphores are available: one for the kernel program and one for the application.  This is only the former. The use of semaphores and spin locks is basically the same. Compared to a spin lock, the semaphore can enter the critical section only when the signal volume process or thread is obtained, and the critical code is executed. The biggest difference between semaphores and spin locks is that when a process attempts to acquire a semaphore that is already locked, the process won't be busy waiting in the distance like a spin lock。 The semaphore is a sleep lock. If there is a task trying to get a semaphore that has been held, The semaphore pushes it into the waiting queue and then lets it sleep。 The processor then gets free to execute other code. When the semaphore-holding process releases the semaphore, a task in the waiting queue will be awakened, thereby obtaining the semaphore. (1) Signal Volume implementation: In Linux, the semaphore is defined as follows:structsemaphore {
spinlock_tLock;//used to protect the count variable.
UnsignedintCount//more than 0, the resource is idle, equals 0, the resource is busy, but no process waits for this protected resource, less than 0, the resource is unavailable, and at least one process waits for the resource.
structList_head wait_list;//stores the address of the waiting queue list, and all sleep processes that are currently waiting for the resource are placed in the list.
};(2) Signal usage: 1)definitionSignal Volume:structSemaphore sem;2)InitializeSignal Volume:StaticInlinevoidSema_init (structSemaphore *sem,intVal);//set SEM to Val

#defineInit_mutex (SEM) sema_init (SEM, 1)//Initializes a user mutex with a semaphore of SEM set to 1
#defineinit_mutex_locked (SEM) sema_init (SEM, 0)//Initializes a user mutex with a semaphore of SEM set to 0The definition and initialization can be completed in one step: Declare_mutex (name);//the macro defines the semaphore name and initializes 1
declare_mutex_locked (name);//the macro defines the semaphore name and initializes 0When the semaphore is used for mutual exclusion (that is, to avoid multiple processes running in a critical section), the value of the semaphore should be initialized to 1. This semaphore can only be owned by a single process or thread at any given time. In this usage mode, a semaphore is also called a mutex (mutex), which is the abbreviation of the mutex (mutual exclusion).  Almost all semaphores in the Linux kernel are used for mutual exclusion. Using semaphores, the kernel code must contain <asm/semaphore.h> 3)GetSemaphore (Locked):voidDownstructSemaphore *sem);//This function causes sleep and cannot be used in an interrupt context .intDown_interruptible (structSemaphore *sem);//after the function enters sleep, it can be awakened by the signalintDown_killable (structSemaphore *sem);

4) releasing the semaphore

voidUp (structsemaphore *sem); //to release the semaphore SEM, wake the waiting person 4. Completion amountIt is used for one execution unit to wait for another execution unit to finish doing something;structCompletion {
UnsignedintDone//A function that is greater than 0 indicates that the completion amount can be executed immediately, not waiting, equals 0, and the thread with the completed amount is placed in a wait state.
wait_queue_head_t wait;
};1)definitionAmount of Completion:structcompletion com;2)Initialize:Init_completion (&com);//If you feel this two-step trouble, you will be given a macro that defines and initializes the declare_completion (COM);3) WaitAmount of Completion:void__sched Wait_for_completion (structCompletion *x);//waiting for a completion to be awakenedint__sched wait_for_completion_interruptible (structCompletion *x);//interruptible wait_for_completionUnsignedLong__sched Wait_for_completion_timeout (structCompletion *x, unsignedLongTimeout);//wait_for_completion with time-out processing4)Wake upAmount of CompletionvoidCompletestructCompletion *x);//only one waiting process or thread is awakened.
voidComplete_all (structCompletion *x);//wake up all processes or threads waiting for this amount of completion

PostScript: In addition to the above several widely used concurrency control mechanism, there are interrupt shielding, sequential lock (Seqlock), RCU (read-copy-update), and so on, do a simple summary such as

concurrency control in Linux drivers

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.