在ARM原子atomic_add?(atomic_add in ARM atomic?)

2019-10-20 03:31发布

按http://lxr.free-electrons.com/source/arch/arm/include/asm/atomic.h#L31

 static inline void atomic_add(int i, atomic_t *v)
 41 {
 42         unsigned long tmp;
 43         int result;
 44 
 45         prefetchw(&v->counter);
 46         __asm__ __volatile__("@ atomic_add\n"
 47 "1:     ldrex   %0, [%3]\n"
 48 "       add     %0, %0, %4\n"
 49 "       strex   %1, %0, [%3]\n"
 50 "       teq     %1, #0\n"
 51 "       bne     1b"
 52         : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
 53         : "r" (&v->counter), "Ir" (i)
 54         : "cc");
 55 }

怎么能叫做原子时,它可以被抢占

Answer 1:

你似乎是完全误解的原子操作是什么。

它应该是很明显,如果你看看x的值,看到的值是13,然后调用由5增加它的atomic_add功能,新的结果可能是什么,因为另一个线程可能已经改变了价值atomic_add被称为前。 同样,如果你检查结果,它可能再次成为什么,因为另一个线程可能会改变atomic_add和你之间的检查结果。

一个atomic_add功能保证离开增加通过量的值。 这就是它做什么。 这是如何实现并不重要。 如果百个线程调用atomic_add(5,&x),则x将最终增加了500这是最重要的。

这是原子操作是如何像ARM和PowerPC有一个预留的存储位置和存储指令核对,保留仍然存在的指令的处理器执行的典型方法。



Answer 2:

ldrexstrex采取执行原子指令不同的默契。 传统的比较和交换 (CAS的简称)在无锁编程限制。 在装载连杆/条件存储 (简称LL / SC)是原子指令 ,它允许原子链表的更高级形式; 对它们进行比较,并考虑如何他们可能会在硅中实现。

对于传统的臂,所述swpswpb指令提供的原子机制。 随着指令在一个周期内完成这似乎是显而易见的。 并发症是在多CPU设计。 运行在CPU swp必须锁定总线,使得其它CPU不能读取或为被执行的更新被写入存储器。 通常情况下,这将是整辆巴士 ,而不仅仅是一个单一的位置。 整辆巴士机制意味着Adhmal的法律适用。

按照Masta79, 原子并不意味着“在一个周期”,是ARM的一个显着特点ldrex / strex原子的支持。 一个特别的储备颗粒被锁定的ARM总线上的持续时间ldrex / strex对。 这使得许多不同的复杂的无锁原语; 许多有效的指令允许之间ldrex / strex对。 然而,它配备了额外的复杂性strex通过条件码被设置支持重试状态。 这是从传统的原子操作的思维定一个明确的转变。 有了具体的保留,可以为每个CPU取得进展,如果他们没有试图锁定在同一时间同一储备granual(内存块特定的)。 这应有助于避免Adhmal路地块 (又名内存带宽,总线锁定)。

怎么能叫做原子时,它可以被抢占?

代码的一个重要特征是prefetchw(&v->counter); ,它带来的价值到缓存中。 高速缓存被当作一个临时的缓冲区和成功strex将提交。 只有缓存的值被修改,直到strex ; 如果strex发现它是脏的(另一个提交它),则该值被丢弃。 同样的CPU上的中断都会做clrex ,这也无效数据,使strex重试。



文章来源: atomic_add in ARM atomic?