The concept of concurrency control
----concurrency refers to the parallel execution of multiple execution units, while concurrent execution units share resources (hardware resources and
Access to global variables, static variables, and so on,----software, can easily lead to race.
What happens in a race
----Multiple CPUs with symmetric multiprocessor (SMP)
----A single CPU process and the process that preempted it
----Interrupts (hard interrupt, soft interrupt, tasklet, bottom half) and process
The way to solve the problem of race state
----guarantee mutually exclusive access to shared resources, so-called mutually exclusive access refers to the time when an execution unit accesses a shared resource.
----Other execution units are blocked from access.
The code that----access the shared resource is called the critical section, and the critical section needs to be protected with some kind of mutex mechanism.
Mutex mechanism
---- Interrupt Masking
---- Atomic Operation
---- Spin lock
---- Signal Volume
Interrupt Masking
----local_irq_disable ()//shielded Interrupt
----/* Critical section */
----local_irq_enable ()//Open Interrupt
----This approach does not solve the race state caused by SMP multi-CPU
Atomic operation
----Implementation method:
----Header File asm/atomic.h
----atomic_t V=atomic_init (1); Defines the atomic variable V and initializes it to 1
----if (! atomic_dec_and_test (v))//self-subtract 1 test
----{atomic_inc (&V); Return–ebusy; }//device busy return error code
----......//Critical area code
----Atomic_inc (&C); Releasing the device
Spin lock
----spinlock_t lock; Defining Spin Locks
----Spin_lock_init (&lock); Initialize spin lock
----Spin_lock (&lock); Get spin Lock
----......//Critical area code
----Spin_unlock (&lock); Release spin lock
----An example:
static int Cdev_open (struct inode*inode, struct file *file)
{
Spin_lock (&lock);
if (flag== 1) {
flag--;
Spin_unlock (&lock);
PRINTK (kern_info "Cdev_open!\n"); Critical section Code
Return0;
}else{
Spin_unlock (&lock);
Return-ebusy;
}
Return0;
}
static int cdev_release (struct inode*inode, struct file *file)
{
flag++;
return 0;
}
----Description: Spin lock is a kind of busy waiting for the lock, there can be no sleep in the middle of the operation; The critical section cannot be too long; spin
----lock can be used in an interrupt context
Signal Volume
----need a header file linux/semaphore.h
----struct semaphore sem; Define the semaphore
----Sema_init (&sem,1); Initialize the semaphore
----Down_interruptible (&SEM); Get the semaphore
----......//Critical area code
----Up (&SEM); Release semaphore
----Description: The semaphore differs from the spin lock, which is a sleep lock that cannot be used in an interrupt context.
----A simple way to use:
----if (Down_trylock (&SEM))//try to open the lock
----Return–ebusy; Device busy
----......//Critical area code
----Up (&SEM); Releasing an open lock
concurrency control in Linux device drivers