1. 中断屏蔽
相关函数
local_irq_disable()
local_irq_enable()
local_irq_save(flags)
local_irq_restore(flags)
local_bh_disable()
local_bh_enable()
模板
local_irq_disable();
//critical section 临界区
local_irq_enable()
例程
void s3c2410_gpio_setpin(unsigned int pin, unsigend int to)
{
void __iomem *base=s3c24xx_GPIO_BASE(pin);
unsigned long offs=s3c2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long dat;
local_irq_save(flags);
dat=__raw_read(base+0x04)
...
__raw_write(dat,base+0x04)
local_irq_restore(flags);
}
2. 信号量(semaphore)
信号量本身是一个整数值,可以大于1,
一对操作函数通常称为P和V
进入临界区(P)
相关信号量上调P
如果信号量>0,该值减一,进程继续
如果信号量=0,进程等待,直到其它释放信号量
退出临界区(V)
信号量的解锁通过调用V完成
该函数增加信号量的值
必要的时候唤醒等待的进程
信号量与互斥体区别
信号量的值可以大于1, 而互斥体值只能为0或者1
初始化信号量
void sema_init(struct semaphore *sem,int val)
初始化静态互斥量
DECLARE_MUTEX(name) //初始化为1
DECLARE_MUTEX_LOCKED(name) //初始化为0
初始化动态互斥量
void init_MUTEX(name) //初始化为1
void init_MUTEX_LOCKED(name) //初始化为0
获取信号量
void down(struct semaphore *sem)//减小信号量的值,如果不能获得就一直等待
int down_interruptible(struct semaphore *sem)//完成和down一样的工作,但是操作是可以中断的
int down_trylock(struct semaphore *sem) //永远不会休眠,如果信号量在调用时不可获得,就会立即返回一个非零值
释放信号量
void up(struct semaphore *sem)
使用信号量模板
DECLARE_MUTEX(sem) //初始化为1
if(down_interruptible(&sem))
{
}
//critical section
up(&sem);
3. 完成量completion
静态初始化 DECLARE_COMPLETION(xxx_completion) //
动态创建 struct completion xxx_completion;//创建一个完成量
init_completion(&xxx_completion)
等待完成量,没有完成之前,当前进程阻塞
void wait_for_completion(struct completion *)
触发完成,唤醒一个等待进程
void complete(struct completion *c)//唤醒一个等待线程
void complete_all(struct completion *c)//唤醒所有等待线程
使用示例
DECLARE_COMPLETION(xxx_comp)
ssize_t complete_read( struct file *file , char __user *buf, size_t count, lofft_t *pos)
{
wait_for_completion(&xxx_comp);
return 0;
}
ssize_t complete_write( struct file *file , char __user *buf, size_t count, lofft_t *pos)
{
completion(&xxx_comp);
return 0;
}
4. 自旋锁
自旋锁是一个互斥设备
如果锁被其它设备获得,则代码进入忙循环,则代码进入忙循环并重复检查这个锁。
自旋锁和信号量的区别:
自旋锁是进入忙循环,即进程不阻塞,不退出,一直在while循环。而信号量是进程阻塞。
初始化自旋锁
spinlock_t xxx_lock=SPIN_LOCK_UNCLKED;
void spin_lock_init(spinlock_t *lock);
锁定函数
void spin_lock(spinlock_t *lock)
获得自旋锁之前禁止中断(包括软件中断和硬件中断)
void spin_lock_irq(spinlock_t *lock)
获得自旋锁之前禁止中断(包括软件中断和硬件中断),中断状态保存在状态字flags中
void spin_lock_irqsave(spinlock_t *lock, unsigned long flags)
获得自旋锁之前禁止软件中断,硬件中断保持打卡
void spin_lock_bh(spinlock_t *lock)
释放自旋锁
void spin_unlock(spinlock_t *lock)
void spin_unlock_irqsave(spinlock_t *lock, unsigned long flags)
void spin_unlock_irqsave(spinlock_t *lock, unsigned long flags)
void spin_unlock_bh(spinlock_t *lock)
自旋锁模板
spinlock_t lock;
void spin_lock_init(spinlock_t &lock);
spin_lock(&lock)
//critical section
spin_unlock(&lock)
5. 原子操作
http://www.jianshu.com/writer#/notebooks/917048/notes/1679174