首页
社区
课程
招聘
[讨论]关于原子操作的问题
发表于: 2011-11-16 16:38 6283

[讨论]关于原子操作的问题

2011-11-16 16:38
6283
小弟不才, 在翻linux源码时,看到了atomic.h,有点疑问,例如下面这个宏:

#define atomic_set(v, i) (((v)->counter) = (i))

就这么直接赋值就能保证是原子的操作?编译器肯定就会为该句生成 incl xxx 之类的指令?再进一步,就算是incl xxx 这句指令 也不能保证是原子的操作的?

还有这个函数:
/**
 * atomic_add_return - add integer to atomic variable
 * @i: integer value to add
 * @v: pointer of type atomic_t
 *
 * Atomically adds @i to @v and returns the result
 */
static inline int atomic_add_return(int i, atomic_t *v)
{
	unsigned long flags;
	int temp;

	raw_local_irq_save(flags); /* Don't trace it in an irqsoff handler */
	temp = v->counter;
	temp += i;
	v->counter = temp;
	raw_local_irq_restore(flags);

	return temp;
}


怎么保证在temp赋值的时候内存总线被lock住,如果没被lock住的话,他是怎么实现原子操作的?

各位说说对原子操作的理解。。

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 209
活跃值: (138)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
有点原子操作是通过cpu的指令完成的,自加、自减、赋值都可以用专门的cpu指令一步到位。因为只有一个指令,无论线程如何切换,都不会被切成两半,所以是“原子操作”。

复杂的原子操作可以通过加锁来完成,单CPU上直接提高自身的中断级别到没有线程切换的级别就行,多CPU下需要使用自旋锁。
2011-11-17 14:51
0
雪    币: 102
活跃值: (85)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
3
原子操作,顾名思义,不可分割
2011-11-17 15:17
0
雪    币: 107
活跃值: (326)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
膜拜2楼的解答啊.........
2011-11-17 15:26
0
雪    币: 692
活跃值: (40)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
你说的原子操作是在单CPU上的,现在是要考虑多核情况,举个例子:
#include <stdio.h>

int main(int argc, char **argv)
{
	volatile int a;
	a = a+1;
	a++;
	return 0;
}

gcc 生成的汇编代码如下:
pushl	%ebp
	movl	%esp, %ebp
	subl	$16, %esp
	movl	-4(%ebp), %eax
	addl	$1, %eax
	movl	%eax, -4(%ebp)
	movl	-4(%ebp), %eax
	addl	$1, %eax
	movl	%eax, -4(%ebp)
	movl	$0, %eax
	leave
	ret

先不考虑中断和线程的切换,可以看出自加和直接赋值加1生成的 汇编代码一样,都有三步,第一,从内存取值movl        -4(%ebp), %eax,第二,给值加1,addl         $1, %eax,第三,把值放回内存,如果不锁内存总线的话,第一个CPU取值再寄存器里给值加1的时候,第二个CPU 接管了内存总线,同样的取值修改,那么最后看到的值就发生错乱了,所以我认为自加,在不锁内存总线的情况下,在多核中,不能 保证是原子操作。这个是多核CPU并发竞争的问题,而你说的是异步的问题,
至于你说 的自悬锁 其内部也是用 原子操作函数对锁计数加减来完成的,所以,自悬锁,从某种意义上来说,也依赖于 原子操作。

记得以前在翻wrk时,微软提供的 interlockincrement,,,,等等系列的函数,实现时也是用汇编指令加lock前缀实现的。

至于汇编指令的 inc dec等,在单核下是原子操作,但在多核下就不敢保证了。。。

个人愚见,忘不吝指正
2011-11-17 15:54
0
雪    币: 412
活跃值: (30)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
6
我估计你看的是未开启smp的代码吧,为开启的时候,就是普通的变量操作,
开启smp的时候,代码是根据不同的处理器使用的原子操作,比如lock前缀
2011-11-17 17:23
0
游客
登录 | 注册 方可回帖
返回
//