免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 14499 | 回复: 15
打印 上一主题 下一主题

问个关于test_and_set_bit()函数的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-27 09:48 |只看该作者 |倒序浏览

  1. #include <linux/module.h>
  2. #include <asm/bitops.h>
  3. #include <linux/init.h>

  4. static int main_init(void)
  5. {
  6.         unsigned long v = 1;

  7.         printk(KERN_INFO "%d\n", test_and_set_bit(0, &v));

  8.         return 0;
  9. }

  10. static void main_exit(void)
  11. {
  12. }

  13. module_init(main_init);
  14. module_exit(main_exit);

  15. MODULE_LICENSE("GPL");
复制代码


手册上说是设置为并返回原来的值,但为什么输出是-1呢,第0位的值应该是1啊,请问我哪里理解错误了,谢谢指教

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
2 [报告]
发表于 2009-11-27 11:07 |只看该作者
理解应该没有错误

论坛徽章:
0
3 [报告]
发表于 2009-11-27 11:09 |只看该作者
兄弟啊 那怎么会是-1啊

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
4 [报告]
发表于 2009-11-27 11:23 |只看该作者
我试了一下,发现同样的问题。估计是因为本身v=1的原因,你将v=0,然后再测试一下

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
5 [报告]
发表于 2009-11-27 11:25 |只看该作者
  5 static int main_init(void)
  6 {
  7         unsigned long v = 0x00;
  8
  9         unsigned long ret = test_and_set_bit(0, &v);
10         printk(KERN_INFO "%x,%x\n", ret, v);
11
12         return 0;
13 }

结果是:
0,1

论坛徽章:
0
6 [报告]
发表于 2009-11-27 11:42 |只看该作者
原帖由 @sky 于 2009-11-27 11:09 发表
兄弟啊 那怎么会是-1啊

不用较真,你只要考虑是 “真” 还是 “假” 就行了

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
7 [报告]
发表于 2009-11-27 11:52 |只看该作者
原帖由 platinum 于 2009-11-27 11:42 发表

不用较真,你只要考虑是 “真” 还是 “假” 就行了

呵呵,-1用无符号表示就是0xFFFFFFF

论坛徽章:
0
8 [报告]
发表于 2009-11-27 12:00 |只看该作者
原帖由 Godbach 于 2009-11-27 11:52 发表

呵呵,-1用无符号表示就是0xFFFFFFF

管他 1 还是 -1,只要判断返回值是 0 还是 !0 就行了,反正是给 if 语句使用的

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
9 [报告]
发表于 2009-11-27 12:10 |只看该作者
恩,也是,主要是和0比较。

不过他的返回值,到底是怎么搞的,为什么不能就是他真正的原始值呢?

论坛徽章:
0
10 [报告]
发表于 2009-11-27 12:48 |只看该作者
x86上的实现:
187/**
188 * test_and_set_bit - Set a bit and return its old value
189 * @nr: Bit to set
190 * @addr: Address to count from
191 *
192 * This operation is atomic and cannot be reordered.
193 * It also implies a memory barrier.
194 */
195static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
196{
197        int oldbit;
198
199        asm volatile(LOCK_PREFIX "bts %2,%1\n\t"
200                     "sbb %0,%0" : "=r" (oldbit), ADDR : "Ir" (nr) : "memory");
201
202        return oldbit;
203}

BTS就是根据位偏移值从位串中取出一位放入CF中,然后将位串中的该位置成1。位基址可以为寄存器或内存寻址;位偏移值可以为寄存器或立即数:

SBB是一条带借位的减法指令,这就是说SBB将第二个操作数(即右操作数)加上标志位CF,然后将结果用第一个操作数来减。

[ 本帖最后由 chenbdchenbd 于 2009-11-27 12:58 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP