ARM 原子操作里的兩個(gè)匯編指令

今天一個(gè)讀者朋友給我留言,問(wèn)了這個(gè)問(wèn)題,ARM原子操作的匯編代碼,還給我截圖了兩個(gè)不同的解釋,讓我說(shuō)哪個(gè)是正確的。
原子操作的起因是為了內(nèi)核同步,保證數(shù)據(jù)在正確性,之前已經(jīng)吹過(guò)一波,可以看這幾篇文章。
CPU和和存儲(chǔ)的連接圖

原子操作的代碼
我截取的這段是ARM7之后的代碼,在ARM6之前的CPU并不支持SMP。所以原子操作的代碼也分成了ARM6之前的和ARM7之后的區(qū)分。
#define?ATOMIC_OP(op,?c_op,?asm_op)?????\
static?inline?void?atomic_##op(int?i,?atomic_t?*v)???\
{?????????\
?unsigned?long?tmp;??????\
?int?result;???????\
?????????\
?prefetchw(&v->counter);??????\
?errata_855872_dmb();??????\
?????????\
?__asm__?__volatile__("@?atomic_"?#op?"\n"???\
"1:?ldrex?%0,?[%3]\n"??????\
"?"?#asm_op?"?%0,?%0,?%4\n"?????\
"?strex?%1,?%0,?[%3]\n"??????\
"?teq?%1,?#0\n"??????\
"?bne?1b"???????\
?:?"=&r"?(result),?"=&r"?(tmp),?"+Qo"?(v->counter)??\
?:?"r"?(&v->counter),?"Ir"?(i)?????\
?:?"cc");???????\
}????
我們主要討論兩個(gè)匯編指令
LDREX
,[]
LDREX 指令從「」中獲取「內(nèi)存地址」,并且將「內(nèi)存地址」的內(nèi)容加載到「」目標(biāo)寄存器中。
STREX
,,[]
STREX 指令從「」中獲取「內(nèi)存地址」,并且將「內(nèi)存地址」的內(nèi)容加載到「」目標(biāo)寄存器中,并且把執(zhí)行結(jié)果保存在 「」。
在執(zhí)行的時(shí)候,還有兩個(gè)監(jiān)視器在共同工作
local monitor 「 本地監(jiān)視器」global monitor「 全局監(jiān)視器」
單CPU執(zhí)行原子操作執(zhí)行的同步情況
單CPU的情況下是不需要global monitor 參與的。

多CPU執(zhí)行原子操作執(zhí)行的同步情況
多CPU的情況下需要global monitor 參與。

關(guān)于這個(gè)同步機(jī)子的C語(yǔ)言嵌入?yún)R編代碼,還有更加詳細(xì)的解釋,大家如果有興趣的話,可以看這幾個(gè)鏈接,會(huì)更加詳細(xì)。
http://www.wowotech.net/linux_kenrel/atomic.html
https://biscuitos.github.io/blog/ATOMIC/

評(píng)論
圖片
表情
