[Development] eleven Embedded Linux driver, Linux concurrent competition - atomic operation, spin locks, semaphores, mutexes

One, atomic operation

Shaping operations atomic API
function description
ATOMIC_INIT(int i) The definition of atomic variables when it is initialized.
int atomic_read(atomic_t *v) Reading the value of v, and returns.
void atomic_set(atomic_t *v, int i) Writes the value of i to v.
void atomic_add(int i, atomic_t *v) Plus the value of i to v.
void atomic_sub(int i, atomic_t *v) Minus the value of i from v.
void atomic_inc(atomic_t *v) Add 1 to v, which is the increment.
void atomic_dec(atomic_t *v) From 1 v Save, Save i.e. from
int atomic_dec_return(atomic_t *v) Save from v 1, and v is the return value.
int atomic_inc_return(atomic_t *v) Add 1 to v, and v return value.
int atomic_sub_and_test(int i, atomic_t *v) Reduced from v i, if the result is zero returns true, false otherwise
int atomic_dec_and_test(atomic_t *v) From v minus 1, if the result is zero returns true, false otherwise
int atomic_inc_and_test(atomic_t *v) Add 1 to v, if the result is zero returns true, false otherwise
int atomic_add_negative(int i, atomic_t *v) Add to v i, if the result is negative returns true, false otherwise
Atomic operations API
function description
void set_bit(int nr, void *p) Nr the first position of the address 1 p.
void clear_bit(int nr,void *p) The first bit is cleared p nr address.
void change_bit(int nr, void *p) The first p-bit address nr flip.
int test_bit (int nr, void * p) to obtain p Of nr bit value of the address.
int test_and_set_bit(int nr, void *p) Nr 1 p position the first address, and returns to the original value of nr bits.
int test_and_clear_bit(int nr, void *p) The first p nr address bit is cleared, and returns to the original value of nr bits.
int test_and_change_bit(int nr, void *p) The first bit flip p nr address, and return to the original position nr

Second, the spin lock

Usage Note the following:

  • ①, because while waiting for the spin lock in "spin" state, the lock hold time is not too long, must be short, otherwise it will reduce system performance. If the critical area is relatively large, run a long time if you want to select other concurrent treatments, such as semaphores talk about later and mutex.
  • ②, spin lock to protect critical areas can not call any API function may cause the thread to sleep, otherwise it could lead to a deadlock.
  • ③, not recursively apply spin lock, because once by applying a recursive way you are holding the lock, then you have to "spin" and wait for the lock to be released, but you are in a "spin" state, did not France releases the lock. The result is that own their own locked up!
  • ④, when writing a driver's driving we must take into account portability, so whether you are using a single-core or multi-core SOC, will it be written as multi-core SOC driver.
The basic spin locks API
function description
DEFINE_SPINLOCK(spinlock_t lock) Define and initialize a variable choice.
int spin_lock_init(spinlock_t *lock) Initialized spin lock.
void spin_lock(spinlock_t *lock) Gets the spin locks, also known as lock.
void spin_unlock(spinlock_t *lock) Free a spin lock.
int spin_trylock(spinlock_t *lock) Attempt to obtain the specified spin lock if not get to return 0
int spin_is_locked(spinlock_t *lock) Check whether the specified spin lock is acquired, if not get returns nonzero, and 0 otherwise.
Interrupt spinlock API
function description
void spin_lock_irq(spinlock_t *lock) Prohibit local interrupt and get the spin lock.
void spin_unlock_irq(spinlock_t *lock) Activate local interrupt, and releases the spin lock.
void spin_lock_irqsave(spinlock_t *lock,unsigned long flags) Save interrupt status prohibits local interrupt and get the spin lock.
void spin_unlock_irqrestore(spinlock_t*lock, unsigned long flags) The interrupt status restored to its previous state, and local interrupt activation, releases the spin lock.
The lower half of the spin lock API
function description
void spin_lock_bh(spinlock_t *lock) Close the bottom half, and get the spin lock.
void spin_unlock_bh(spinlock_t *lock) Open the bottom half, and releases the spin lock.

Third, the semaphore

Use semaphores will improve the efficiency of the processor, after all, have been silly not there "spin" Wait. However, semaphores spinlock overhead than big, because it will switch threads, thread switching semaphore the thread to sleep later there will be overhead.

Usage Note the following:

  • ①, because semaphores can cause the thread to sleep to wait for resources, and therefore suitable for those relatively long footprint occasions.
  • ②, thus the semaphore can not be used to interrupt , because semaphores can cause sleep interruption can not sleep.
  • ③, if the shared resource holding time is relatively short, it is not suitable for use semaphores , because the overhead of frequent sleep, causing the thread switching is much larger than the amount that brings the signal point advantage.
Semaphore API
function description
DEFINE_SEAMPHORE(name) Define a semaphore, and set the semaphore is 1.
void sema_init(struct semaphore *sem, int val) 初始化信号量 sem,设置信号量值为 val。
void down(struct semaphore *sem) 获取信号量,因为会导致休眠,因此不能在中断中使用。
int down_trylock(struct semaphore *sem); 尝试获取信号量,如果能获取到信号量就获取,并且返回 0。如果不能就返回非 0,并且不会进入休眠。
int down_interruptible(struct semaphore *sem) 获取信号量,和 down 类似,只是使用 down 进入休眠状态的线程不能被信号打断。而使用此函数进入休眠以后是可以被信号打断的。
void up(struct semaphore *sem) 释放信号量

四、互斥体

使用注意如下:

  • ①、 mutex 可以导致休眠,因此不能在中断中使用 mutex,中断中只能使用自旋锁。
  • ②、和信号量一样, mutex 保护的临界区可以调用引起阻塞的 API 函数。
  • ③、因为一次只有一个线程可以持有 mutex,因此,必须由 mutex 的持有者释放 mutex。并且 mutex 不能递归上锁和解锁
互斥体API
函数 描述
DEFINE_MUTEX(name) 定义并初始化一个 mutex 变量。
void mutex_init(mutex *lock) 初始化 mutex。
void mutex_lock(struct mutex *lock) 获取 mutex,也就是给 mutex 上锁。如果获取不到就进休眠。
void mutex_unlock(struct mutex *lock) 释放 mutex,也就给 mutex 解锁。
int mutex_trylock(struct mutex *lock) 尝试获取 mutex,如果成功就返回 1,如果失败就返回 0。
int mutex_is_locked(struct mutex *lock) 判断 mutex 是否被获取,如果是的话就返回1,否则返回 0。
int mutex_lock_interruptible(struct mutex *lock) 使用此函数获取信号量失败进入休眠以后可以被信号打断。
发布了716 篇原创文章 · 获赞 1197 · 访问量 85万+

Guess you like

Origin blog.csdn.net/ReCclay/article/details/105152695