1 中斷屏蔽
#include <linux/irqflags.h>
local_irq_disable();
local_irq_enable();
local_irq_save(flags);
local_irq_restore(flags);
2 原子操作
#include <asm/atomic.h>
atomic_t v;
v=ATOMIC_INIT(i);
atomic_set(&v, i);
atomic_read(v);
void atomic_add(int i, atomic_t *v);
void atomic_sub(int i, atomic_t *v);
void atomic_inc(atomic_t *v);
void atomic_dec(atomic_t *v);
atomic_sub_and_test(i, v);
atomic_dec_and_test(v);
atomic_inc_and_test(v);
atomic_dec_return(v);
atomic_inc_return(v);
int atomic_add_negative(int i, atomic_t *v)
3 自旋鎖
自旋鎖在獲取鎖之前一直進入忙循環並重複檢查鎖是否被解鎖,可用於不能休眠的流程中,例如中斷處理等。
擁有自旋鎖時禁止中斷;
自旋鎖擁有時間儘可能短;
自旋鎖下的執行函數不能休眠;
1.普通自旋鎖
#include <linux/spinlock.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
spinlock_t lock=SPIN_LOCK_UNLOCK;
#else
DEFINE_SPINLOCK(lock);
#endif
spin_lock_init(&lock);
void spin_lock(&lock);
void spin_lock_bh(&lock);
void spin_lock_irq(&lock);
spin_lock_irqsave(&lock, flags);
void spin_unlock(&lock);
void spin_unlock_bh(&lock);
void spin_unlock_irq(&lock);
void spin_unlock_irqrestore(&lock, flags);
非阻塞自旋鎖獲取:
成功返回非零值,否則返回零
int spin_trylock(&lock);
int spin_trylock_bh(&lock);
int spin_trylock_irq(&lock);
2.讀寫自旋鎖
#include <linux/rwlock.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
rwlock_t lock=RW_LOCK_UNLOCK;
#else
DEFINE_RWLOCK(lock);
#endif
rwlock_init(&lock);
read_lock(&lock);
read_lock_bh(&lock);
read_lock_irq(&lock);
read_lock_irqsave(&lock, flags);
read_unlock(&lock);
read_unlock_bh(&lock);
read_unlock_irq(&lock);
read_unlock_irqrestore(&lock, flags);
write_lock(&lock);
write_lock_bh(&lock);
write_lock_irq(&lock);
write_lock_irqsave(&lock, flags);
write_unlock(&lock);
write_unlock_bh(&lock);
write_unlock_irq(&lock);
write_unlock_irqrestore(&lock, flags);
非阻塞自旋鎖獲取:
成功返回非零值,否則返回零
read_trylock(&lock);
read_unlock_irqrestore(&lock, flags);
write_trylock(&lock);
4 信號量
信號量在獲取過程中會休眠,所以不能用於不能休眠的流程中,例如中斷處理等。
1.普通信號量
#include <asm/semaphore.h>
struct semaphore sem;
初始化方式一:
void sema_init(&sem,val);
初始化方式二:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
DECLARE_MUTEX(sem);
#else
DEFINE_SEMAPHORE(sem);
#endif
初始化方式三:
void init_MUTEX(&sem);
void init_MUTEX_LOCKED(&sem);
void down(&sem);
int down_interruptible(&sem);
int down_trylock(&sem);
void up(&sem);釋放信號量
2.讀寫信號量
#include <linux/rwsem.h>
struct rw_semaphore rw_sem;
void init_rwsem(&rw_sem);
void down_read(&rw_sem);
int down_read_trylock(&rw_sem);
void up_read(&rw_sem);釋放信號量
void down_write(&rw_sem);
int down_write_trylock(&rw_sem);
void up_write(&rw_sem);釋放信號量
void downgrade_write(&rw_sem);
5 互斥體
互斥體的使用方法和場景與信號量完全一樣。
#include <linux/mutex.h>
struct mutex mux;
mutex_init(mutex);
void mutex_lock(struct mutex *lock);
int __must_check mutex_lock_interruptible(struct mutex *lock);
int mutex_trylock(struct mutex *lock);
void mutex_unlock(struct mutex *lock);
6 completion
常用於進程、線程間同步
#include <linux/completion.h>
DECLARE_COMPLETION(comp);
struct completion comp;
void init_completion(&comp);
void wait_for_completion(&comp);
void complete(&comp);
void complete_all(&comp);
7 位操作
#include <asm/bitops.h>
void set_bit(int nr, volatile unsigned long *addr);
void clear_bit(int nr, volatile unsigned long *addr);
void change_bit(int nr, volatile unsigned long *addr);
int test_and_set_bit(int nr, volatile unsigned long *addr);
int test_and_clear_bit(int nr, volatile unsigned long *addr);
int test_and_change_bit(int nr, volatile unsigned long *addr);
8 seqlock
#include <linux/seqlock.h>
DEFINE_SEQLOCK(lock);
seqlock_init(lock);
unsigned read_seqbegin(const seqlock_t *sl);
void write_seqlock(seqlock_t *sl);
void write_sequnlock(seqlock_t *sl);
以上的讀寫函數還有很多變種,需要的請查看include/linux/seqlock.h文件
9 RCU(讀取-複製-更新)
#include <linux/rcupdate.h>
void rcu_read_unlock(void);
void rcu_read_lock(void);
void call_rcu(struct rcu_head *head,void (*func)(struct rcu_head *head));