Chinaunix首页 | 论坛 | 博客
  • 博客访问: 235725
  • 博文数量: 82
  • 博客积分: 30
  • 博客等级: 民兵
  • 技术积分: 505
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-23 14:59
文章分类

全部博文(82)

文章存档

2015年(81)

2011年(1)

我的朋友

分类: 嵌入式

2015-04-03 18:05:34

网上说:
#if 0 /* Fool kernel-doc since it doesn't do macros yet */  
/** 
 * test_bit - Determine whether a bit is set 
 * @nr: bit number to test 
 * @addr: Address to start counting from 
 */  
static int test_bit(int nr, const volatile void * addr);  
#endif  
static __always_inline int constant_test_bit(int nr, const volatile unsigned long *addr)  
{  
    return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;  
}  
 

1.对于编译时的常数使用上面的函数进行判断

假设我们要测试的数为test = 0x00000008,它的第三位是否为1(位数是从0数起),即nr = 3 = 0x00000003,addr就是我们测试的数的地址

addr = &test; 对于运算addr[nr >> 5] = addr[0] 也就是test的值

对于前面部分 1UL左移3位,其值就是0x00000008,它们&运算后,结果是0x00000008 != 0,所以return的结果返回是1

即0x00000008的第3位是1,其结果也确实是1。其他的情况照样子可以这样子验证。

问题:
1.什么是原子的位操作?为什么说函数test_bit是唯一一个不需要是原子的位操作?
2.如果test =0x00008000,函数_test_bit还能测出第7位为1吗?addr[nr >> 5] = addr[7>>5]= addr[7>>5]=addr[0]=0x00008000,故((1UL << (nr & 31)) & (addr[nr >> 5])) -->((0x00008000) & (0x00008000) != 0,即:返回值仍为1!正确!
另:
test_bit (int nr, const volatile void *addr)
{
return 1 & (((const volatile __u32 *) addr)[nr >> 5] >> (nr & 31));
}
static inline int test_bit(int nr, const unsigned long *vaddr)
{
return (vaddr[nr >> 5] & (1UL << (nr & 31))) != 0;
}

阅读(3649) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~