Chinaunix首页 | 论坛 | 博客
  • 博客访问: 690914
  • 博文数量: 192
  • 博客积分: 1875
  • 博客等级: 上尉
  • 技术积分: 2177
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-23 23:21
个人简介

有时候,就是想窥视一下不知道的东东,因为好奇!

文章分类

全部博文(192)

文章存档

2024年(8)

2023年(3)

2020年(1)

2019年(1)

2018年(1)

2017年(2)

2016年(69)

2015年(53)

2014年(14)

2013年(1)

2012年(5)

2011年(25)

2010年(9)

分类: LINUX

2011-02-10 18:49:00

                                                                            原子操作

.面临的问题:

     一些汇编语言指令具有读"-修改-写"类型,即访问存储器单元时,先读原值,再写新值。在多个CPU上的多个内核控制路径同时“读-修改-写”同一个单元时,会造成受访数据的混乱。

      如:两个CPU都访问同一单元,但是存储器仲裁器只允许其中的一个访问而让另一个延迟。当第一个读操作已经完成后,延迟的CPU从那个存储单元正好读到同一个旧值。然后,两个CPU都试图向那个存储器写新值,总线存储器访问再一次被存储仲裁器串行化,最终,两个写操作都成功。显然,从全局来看,结果是不对的。因为访问后的存储器的值,很可能只是后写入的内核控制路径写入的值。

2.问题的一个解决方式:

     为避免上面"-修改-写"指令引起的竟争条件, 一个办法就是,确保这样的操作在工芯片级是原子的。任何一个这样的操作都以单个指令执行,中间不能中断,且避免其他的CPU访问同一个存储单元。

3.Linux内核中提供的的解决方式:

     在编写c代码程序时,并不能保证编译器会为a=a+1a++这样的操作使用一个原子指令。Linux内核提供了一个专门的atomic_t类型和一些专门的函数和宏,作用于atomic_t类型的变量,并当作单独的,原子的汇编语言指令来使用。

4.linux中的原子操作函数

atomic_read(v)                                   返回*v

atomic_set(v, i)                                   *置成i


atomic_add(i, v)                                  i加到*v

atomic_add_return(i, v)                    i加到*v, 返回*v的新值

atomic_add_negative(i, v)                 i加到*v, 若结果为负,则返回1,否则返回0


atomic_sub(i, v)                                  从中*v减去i

atomic_sub_return(v)                       从中*v减去i, 返回*v的新值

atomic_sub_and_test(i, v)                 从中*v减去i, 如果结果为0,返回1,否则返回0


atomic_inc(v)                                     *v值加1

atomic_inc_and_test(v)                    *v值加1, 如果结果为0,返回1,否则返回0

atomic_inc_return(v)                       *v值加1,返回*v新值


atomic_dec(v)                                   *v值减1

atomic_dec_and_test(v)                  *v值减1,如果结果为0,返回1,否则返回0

atomic_dec_return(v)                      *v值减1,返回*v新值


linux中的原子位处理函数

test_bit(nr, addr)                              返回*addr的第nr位的值

set_bit(nr, addr)                               设置*addr的第nr

clear_bit(nr, addr)                            清除*addr的第nr

change_bit(nr, addr)                        转换*addr的第nr

test_and_set_bit(nr, addr)               设置*addr的第nr, 并返回它的原值

test_and_clear_bit(nr, addr)           清除*addr的第nr, 并返回它的原值

test_and_change_bit(nr, addr)       转换*addr的第nr, 并返回它的原值

atomic_clear_mask(mask, addr)     清除mask指定的*addr的所有位

atomic_set_mask(mask, addr)         设置mask指定的*addr的所有位

阅读(779) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:优化和内存屏障

给主人留下些什么吧!~~