什么是GCC内置的原子集?

时间:2018-04-20 01:56:24

标签: c gcc atomic

我在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);
}

但是如果我使用这个例子,并在临界区内进行原子设置,那么不必要地对不同变量的原子集进行序列化。

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

2 个答案:

答案 0 :(得分:0)

根据定义,需要同时使用

  

__ sync_synchronize(...)

     

这种内置会发出完整的内存障碍。输入

__ sync_lock_test_and_set(输入* ptr,类型值,...)

  

英特尔所描述的这种内置设备并不是传统的测试套装   操作,而是原子交换操作。它写出了价值   进入* ptr,并返回* ptr的先前内容。很多目标   对这种锁只有最小的支持,并且不支持完整   交换操作。在这种情况下,目标可以支持减少   这里存储的唯一有效值的功能是   立即常数1.实际存储在* ptr中的确切值是   实施定义。

     

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

     

void __sync_lock_release(type * ptr,...)

     

这个内置发布了   由__sync_lock_test_and_set获取的锁。通常这意味着写作   常数0到* ptr。这种内置不是一个完整的障碍,而是   释放障碍。这意味着以前的所有内存都是   全局可见,并且所有以前的内存负载都已满足,   但不会阻止推测以下内存读取   在障碍之前。

答案 1 :(得分:0)

我提出了这个解决方案。如果你认识一个更好的,请回复:

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);
}