• 关于Spinlock机制的一点思考


    存在两段代码同时在多核上执行的情况,这时候才需要一个真正的锁来宣告代码对资源的占有。

    几个核可能会同时access临界区,这时的spinlock是如何实现的呢?

    要用到CPU提供的一些特殊指令,对lock变量进行原子操作。

    SMP中spin_lock的实现

    实现在include/linux/spinlock_api_smp.h

    static inline void __raw_spin_lock(raw_spinlock_t*lock)

    {

    preempt_disable(); 

    spin_acquire(&lock->dep_map, 0, 0,_RET_IP_); 

    LOCK_CONTENDED(lock, do_raw_spin_trylock,do_raw_spin_lock);}

    SMP上的实现被分解为三句话。

    Preempt_disable() 关抢占

    Spin_acquire()是sparse检查需要

    LOCK_CONTENDED()是一个宏,如果不考虑CONFIG_LOCK_STAT(该宏是为了统计lock的操作),则:

    #define LOCK_CONTENDED(_lock, try, lock)    lock(_lock)

    则第三句话等同于:

    do_raw_spin_lock(lock)

    而do_raw_spin_lock()则可以从spinlock.h中找到痕迹:

    static inline intdo_raw_spin_trylock(raw_spinlock_t *lock){    return arch_spin_trylock(&(lock)->raw_lock);}

    看到arch,我们明白这个函数是体系相关的。下面分别分析ARM和x86体现结构下该函数的实现。

    ARM中spin_lock的实现

    static inline voidarch_spin_lock(arch_spinlock_t *lock)

    {

    unsigned long tmp;

    __asm__ __volatile__("

    1: ldrex %0, [%1] "

    @将&lock->lock地址中的值,即lock->lock加载到tmp中,并设置&lock->lock为独占访问"
    teq %0, #0 "

    @测试tmp是否为0

    WFE("ne")

    @不为0,则执行WFE指令。不为0,代表锁已被锁定,则通过WFE指令进入suspendmode(clock停止),直到该锁被释放时发出的SEV指令,CPU才会跳出suspend mode"

    strexeq %0, %2, [%1] "

    @将lock->lock加1,并解除lock->lock的锁定状态,tmp中存入返回状态"

    teqeq %0, #0 "

    @如果执行成功,则tmp为0,成功获得所"

    bne 1b"

    @如果执行不成功,则tmp不为0,跳转到标号1处,继续获得锁。

    : "=&r" (tmp)

    : "r" (&lock->lock),"r" (1) : "cc")

    smp_mb(); }

    代码是一段内联汇编。Tmp为输出,放在寄存器中,在代码中以%0表示,&lock->lock为输入参数1,放在寄存器中,在代码中以%1表示,常数

    1为输入参数2,放在寄存器中,在代码中以2%表示。

    代码中,ldrex/strex以及WFE指令是关键。因lock->lock放在内存中,那么将lock->lock加1这一操作会经过读取内存,+1,写内存的操作,这一过程如果不是原子操作,那么其他核有可能在这一过程中访问lock->lock,造成错误。Ldrex/strex是ARM在arm v6中新增的指令,用于对内存区域的独占访问,WFE指令则可以在空等时间内暂停CPU的时钟,以达到省电的目的。

    原文链接:http://blog.csdn.net/av_geek/article/details/41366539

  • 相关阅读:
    anything vs everything
    cong
    invalid initialization of non-const reference of type与discards qualifiers
    gvew
    3.2存储器层次结构 -- 《深入理解计算机系统》☆☆☆☆☆
    2.2优化编译器的能力和局限性
    2.1.2优化程序性能
    2.1.1优化程序性能
    linux中获取堆栈空间大小的方法
    优美的英文诗歌Beautiful English Poetry
  • 原文地址:https://www.cnblogs.com/ranson7zop/p/7851166.html
走看看 - 开发者的网上家园