" ldaxrh %w2, %4\n"----(A)---------其他cpu唤醒本cpu,获取当前owner值
" eor %w1, %w2, %w0, lsr #16\n"---------自己的号码牌是否等于owner?
" cbnz %w1, 2b\n"----------如果等于,持锁进入临界区,否者回到2,即继续spin
/* We got the lock. Critical section starts here. */
"3:"
: "=&r" (lockval), "=&r" (newval), "=&r" (tmp), "+Q" (*lock)
: "Q" (lock->owner), "I" (1 << TICKET_SHIFT)
: "memory");
}
基本的代码逻辑的描述都已经嵌入代码中,这里需要特别说明的有两个知识点:
(1)Load-Acquire/Store-Release指令的应用。Load-Acquire/Store-Release指令是ARMv8的特性,在执行load和store操作的时候顺便执行了memory barrier相关的操作,在spinlock这个场景,使用Load-Acquire/Store-Release指令代替dmb指令可以节省一条指令。上面代码中的(A)就标识了使用Load-Acquire指令的位置。Store-Release指令在哪里呢?在arch_spin_unlock中,这里就不贴代码了。Load-Acquire/Store-Release指令的作用如下:
-Load-Acquire可以确保系统中所有的observer看到的都是该指令先执行,然后是该指令之后的指令(program order)再执行
-Store-Release指令可以确保系统中所有的observer看到的都是该指令之前的指令(program order)先执行,Store-Release指令随后执行
(2)第二个知识点是关于在arch_spin_unlock代码中为何没有SEV指令?关于这个问题可以参考ARM ARM文档中的Figure B2-5,这个图是PE(n)的global monitor的状态迁移图。当PE(n)对x地址发起了exclusive操作的时候,PE(n)的global monitor从open access迁移到exclusive access状态,来自其他PE上针对x(该地址已经被mark for PE(n))的store操作会导致PE(n)的global monitor从exclusive access迁移到open access状态,这时候,PE(n)的Event register会被写入event,就好象生成一个event,将该PE唤醒,从而可以省略一个SEV的指令。
注:
(1)+表示在嵌入的汇编指令中,该操作数会被指令读取(也就是说是输入参数)也会被汇编指令写入(也就是说是输出参数)。
(2)=表示在嵌入的汇编指令中,该操作数会是write only的,也就是说只做输出参数。
![]()
(3)I表示操作数是立即数
spin_lock的分析文章Google一下有很多,这里只是分享一些关于spin_lock思考过的问题。
一、UP 下spin_lock的实现
UP的情况下,spin_lock本身并没有实现锁机制,相对应的spin_lock()只是禁用了内核抢占而已。如下代码:
//@include/linux/spinlock_api_up.h
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-77053-8.html
一年定期利率是1
你他喵的事看热闹不嫌事大
然后趁机在南海岛礁上加强军事化