OK6410之原子变量

当设备被一个程序打开时,存在被另一个程序打开的可能,如果两个或多个程序同时对设备文件进行写操作,这就是说我们的设备资源同时被多个进程使用,对共享资源(硬件资源、和软件上的全局变量、静态变量等)的访问则很容易导致竞态。

对于竟态问题有不同的处理方式,比如信号量,自旋锁等。

 

但是当共享的资源只是一个简单的整数,这时候我们如果利用完整的锁机制会是一种浪费,这种情况下一般使用原子变量来处理。

 

原子的整形变量为atomic_t,在头文件<asm/atomic.h>中定义

原子变量的相关操作函数如下

1)atomic_t v = ATOMIC_INIT(0);         //定义原子变量v并初始化为0

2)atomic_read(atomic_t *v);            //返回原子变量的值

3)void atomic_inc(atomic_t *v);        //原子变量增加1

4)void atomic_dec(atomic_t *v);        //原子变量减少1

5)int atomic_dec_and_test(atomic_t *v); //自减操作后测试其是否为0,为0则返回true,否则返回false。

除了以上函数之外的其他函数可以自行搜索

atomic_t数据项只能通过上诉的函数进行操作,如果将atomic_t变量传递给需要整型变量的参数,会导致编译出错!!

 

(1)创建原子变量

atomic_t open = ATOMIC_INIT(1)

创建原子变量open并且赋值为1。也可以在编译时利用ATMOIC_INIT宏来初始化原子变量的值。

(2)原子变量读取、计算、判断

if(!atomic_dec_and_test(&open))
{
    atomic_inc(&open);
    return -EBUSY
}

在open()函数里放入上述语句。则在某个设备打开后open - 1 = 0,因此函数返回true,从而if不成立。这个时候能够正常打开驱动。

 

设备A调用了驱动程序后open - 1 = 0,若这个时候设备B也想要调用驱动程序,open - 1 =  -1。则函数返回false,因此if成立,open + 1 = 0之后返回-EBUSY。此时设备B无法运行,这样就能防止两个设备同时运行。

 

atomic_dec_and_test()函数一旦运行则不会被打断,因此不存在设备A读取了open变量为1之后,被另一个设备B中断,使得设备B读取的open也为1,从而导致两个设备都能正常运行,导致竞态。这也是使用原子变量而不是使用普通变量的原因。

 

(3)release函数添加

在release函数中添加以下语句

atomic_inc(&open);

 

测试程序:

int main(int argc,char **argv)
{
  int oflag;
  unsigned int val=0;     
  fd=open("/dev/buttons",O_RDWR);          
  if(fd<0)
  {
     printf("can't open, fd=%d\n",fd);
     return -1;
   }
   while(1)
   { 
     read( fd, &ret, 1);              //读取驱动层数据
     printf("key_vale=0X%x\r\n",ret);   
   }  

   return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值