critical section Linux内核同步 - spin_lock(7)

电脑杂谈  发布时间:2018-02-14 08:19:43  来源:网络整理

" bne 1b"

: "=&r" (lockval), "=&r" (newval), "=&r" (tmp)

: "r" (&lock->slock), "I" (1 << TICKET_SHIFT)

: "cc");

while (lockval.tickets.next != lockval.tickets.owner) {------------(5)

wfe();-------------------------------(6)

lockval.tickets.owner = ACCESS_ONCE(lock->tickets.owner);------(7)

}

smp_mb();------------------------------(8)

}

(1)和preloading cache相关的操作,主要是为了性能考虑

(2)将slock的值保存在lockval这个临时变量中

(3)将spin lock中的next加一

(4)判断是否有其他的thread插入。更具体的细节参考Linux内核同步机制之(一):原子操作中的描述

(5)判断当前spin lock的状态,如果是unlocked,那么直接获取到该锁

(6)如果当前spin lock的状态是locked,那么调用wfe进入等待状态。更具体的细节请参考ARM WFI和WFE指令中的描述。

(7)其他的CPU唤醒了本cpu的执行,说明owner发生了变化,该新的own赋给lockval,然后继续判断spin lock的状态,也就是回到step 5。

(8)memory barrier的操作,具体可以参考memory barrier中的描述。

arch_spin_lock函数ARM64的代码(来自4.1.10内核)如下:

static inline void arch_spin_lock(arch_spinlock_t *lock)

{

unsigned int tmp;

arch_spinlock_t lockval, newval;

asm volatile(

/* Atomically increment the next ticket. */

" prfm pstl1strm, %3\n"

"1: ldaxr %w0, %3\n"-----(A)-----------lockval = lock

" add %w1, %w0, %w5\n"-------------newval = lockval + (1 << 16),相当于next++

" stxr %w2, %w1, %3\n"--------------lock = newval

" cbnz %w2, 1b\n"--------------是否有其他PE的执行流插入?有的话,重来。

/* Did we get the lock? */

" eor %w1, %w0, %w0, ror #16\n"--lockval中的next域就是自己的号码牌,判断是否等于owner

" cbz %w1, 3f\n"----------------如果等于,持锁进入临界区

/*

* No: spin on the owner. Send a local event to avoid missing an

* unlock before the exclusive load.

*/

" sevl\n"

"2: wfe\n"--------------------否则进入spin


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-77053-7.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    • 孙氏
      孙氏

      男女比例失调正常因为重男轻女

      • 东堂明
        东堂明

        最贵的车由马云出品

    • 杨艳华
      杨艳华

      全世界都知道美国是中东乱局始作俑者

    • 王栋鑫
      王栋鑫

      还有哪个品牌在做这个芝麻糊不就知道了

    热点图片
    拼命载入中...