linux驱动中锁的使用

来源:互联网 发布:ubuntu软件源不能更新 编辑:程序博客网 时间:2024/06/03 14:24

一、atomic用法

TP代码中每个判断irq_enable的地方全部换成atomic_cmpxchg,对比和设值一起做完,避免在disable已经判断完毕,但是还没给flag赋值时,被中断打断,再次执行disable,中断函数结束后又执行一次disable,每次执行disable都会对desc->depth++,所以连续加两次。之后enable++一次,无法正常使能中断,TP失效。

#include<linux/atomic.h>

static atomic irq_enabled=ATOMIC_INIT(0);

Void gtp_irq_disable(void)

{

if(atomic_cmpxchg(&irq_enabled,1,0))//比较“1”和irq_enabled的值,如果相等,把“0”赋值给原子变量,返回irq_enabled的值

disable_irq(touch_irq);

}

 

Void gtp_irq_enable(void)

{

if(atomic_cmpxchg(&irq_enabled,1,0))//比较“1”和irq_enabled的值,如果相等,把“0”赋值给原子变量,返回irq_enabled的值

enable_irq(touch_irq);

}

 

Void tpd_irq_registration(void)

{

......

atomic_set(&irq_enabled,1);

}

二、spinlock用法

Busy-waiting,锁定临界区小,自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁。(防止被中断打断)

更保险的方法或许是先(保守的)使用 Mutex,然后如果对性能还有进一步的需求,可以尝试使用spin lock进行调优

 

#include<linux/spinlock.h>

static DEFINE_SPINLOCK(test_lock);

 

int init_test_lock(void)

{

spin_lock_init(&test_lock);

return 0

}//在自旋锁使用之前调用,可以写probe

 

int test(void)

{

......

......

spin_lock(&test_lock);

XXXXX;

XXXXX;

spin_unlock(&test_lock);

.......

.......

}

 

 

三、Mutex的用法

Mutexsleep-waiting,不会一直等待,进程级别的,进程调用时间较长时使用

#include<linux/mutex.h>

static DEFINE_MUTEX(text_lock);//mutex中,如果CONFIG_DEBUG_MUTEXES定义了,会自动init

 

Int test(void)

{

...................

...................

mutex_lock(&test_lock);

XXXXXXXXXXXX;

XXXXXXXXXXXX;

mutex_unlock(&test_lock);

..........

}


代码可直接复制使用,但未经允许,请勿转载

原创粉丝点击