一、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的用法
Mutex是sleep-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);
..........
}
代码可直接复制使用,但未经允许,请勿转载