c - 原子集内置的 GCC 是什么?



我在 https://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html 看到内置列表。但是对于原子集,是否需要使用__sync_lock_test_and_set和__sync_lock_release对?

我在 https://attractivechaos.wordpress.com/2011/10/06/multi-threaded-programming-efficiency-of-locking/上看到了这个例子。

volatile int lock = 0;
void *worker(void*)
{
while (__sync_lock_test_and_set(&lock, 1));
// critical section
__sync_lock_release(&lock);
}

但是,如果我使用此示例,并在关键部分中执行我的原子集,则不同变量的原子集将被不必要地序列化。

感谢关于如何做一个原子集的任何输入,其中我有多个原子变量。

根据定义需要同时使用两者

__sync_synchronize (...

此内置会发出完整的内存屏障。 类型

__sync_lock_test_and_set(键入 *ptr、键入值等)

正如英特尔所描述的,这个内置不是传统的测试和设置。 操作,而是原子交换操作。它写入值 到 *PTR 中,并返回 *PTR 的先前内容。许多目标 对此类锁的支持很少,并且不支持完整的 交易所操作。在这种情况下,目标可能支持减少 此处存储的唯一有效值的功能是 即时常数 1.实际存储在 *ptr 中的确切值为 已定义实现。

这个内置的不是完全的障碍,而是一个获取障碍。 这意味着内置之后的引用不能移动到(或 推测)之前内置,但以前的内存存储可能不会 尚未全局可见,以前的内存负载可能尚未 满意。

无效__sync_lock_release(类型 *PTR, ...)

这内置释放了 __sync_lock_test_and_set获得的锁。通常这意味着写作 常量 0 到 *PTR。这个内置不是完全的屏障,而是 释放屏障。这意味着所有以前的内存存储都是 全局可见,并且已满足所有以前的内存负载, 但不会阻止以下内存读取被推测为 在屏障之前。

我想出了这个解决方案。 如果您知道更好的,请回复:

typedef struct {
volatile int lock;  // must be initialized to 0 before 1st call to atomic64_set
volatile long long counter;
} atomic64_t;
static inline void atomic64_set(atomic64_t *v, long long i)
{
// see https://attractivechaos.wordpress.com/2011/10/06/multi-threaded-programming-efficiency-of-locking/
// for an explanation of __sync_lock_test_and_set
while (__sync_lock_test_and_set(&v->lock, 1)) { // we don't have the lock, so busy wait until
while (v->lock);                            // it is released (i.e. lock is set to 0)
}                                               // by the holder via __sync_lock_release()
// critical section
v->counter = i;
__sync_lock_release(&v->lock);
}

最新更新