内置gcc螺旋锁

时间:2012-01-03 17:27:17

标签: c linux

如何确保在互斥锁期间由多个CPU内核写入的数据在所有内核的所有L1缓存中同步?我不是在谈论代表锁的变量,我在谈论锁中涉及的内存位置。

这适用于Linux,x86_64,我的代码是:

#include <sys/types.h>
#include "dlog.h"

uint *dlog_line;
volatile int dlog_lock;

char *dlog_get_new_line(void) {
    uint val;

    while(!__sync_bool_compare_and_swap(&dlog_lock, 0, 1)) {
        val=*dlog_line;
        if (val==DT_DLOG_MAX_LINES) val=0;
        *dlog_line=val;
    }

    dlog_lock = 0;
}

这里,在dlog_get_new_line()函数中,我使用gcc内置函数,因此获取锁定应该没有任何问题。但是,如何确保在释放锁定时,* dlog_line指向的值会传播到系统中所有其他CPU核心的所有L1缓存中?

我不使用pthread,每个进程在不同的cpu核心上运行。

2 个答案:

答案 0 :(得分:3)

您感兴趣的内容称为cache coherence这是由硬件自动完成的。

简而言之,如果您正确使用__sync_bool_compare_and_swap()(或任何其他锁定内在函数),则无需执行任何操作。

作为一个过度解释的解释,线程将不会从对__sync_bool_compare_and_swap()的调用返回,直到所有其他处理器都能够看到新值或者知道他们的本地副本已过期。


如果您对下面(在硬件中)发生的事情感兴趣,可以使用各种缓存一致性算法来确保核心不会读取过时的数据副本。

以下是常用教学协议的部分列表:

  1. MSI
  2. MESI
  3. Firefly
  4. 现代硬件通常会有更复杂的算法。

答案 1 :(得分:0)

Gcc还有另外两个内置版,它们是为您描述的目的而发明的:__sync_lock_test_and_set__sync_lock_release。它们具有所谓的获取/释放语义,可以保证在保持自旋锁时,您需要的其他变量的存储值是可见的。这些要求比__sync_bool_compare_and_swap提供的要弱一些,因此最好使用为工作量身定制的工具。

他们应该很好地适应不同硬件的容量。例如,在我的x86_64上,这会将最终原子存储区之前的mfence指令放入dlog_lock,但在不同的硬件上,这将适用于可用的指令集。

相关问题