1.RH850U2A上的Splinlock實(shí)現(xiàn)
LDL和STC指令可用于獲取原子讀-寫操作,用于多核系統(tǒng)對內(nèi)存更新進(jìn)行精確處理。LDL和STC指令的操作方式如下。
1.1 Link
每個(gè)CPU只能創(chuàng)建一個(gè)Link(LLbit)。該鏈接包含關(guān)于創(chuàng)建它的地址的信息,并根據(jù)STC指令在該地址是否成功或失敗以及該鏈接是否丟失來進(jìn)行接下來的控制。該鏈接還包括創(chuàng)建鏈接時(shí)的數(shù)據(jù)大小信息,因此,數(shù)據(jù)大小與創(chuàng)建鏈接的LDL指令不同的任何STC指令總是會(huì)失敗,STC指令失敗則該鏈接被刪除。
1.2 Link generation
每個(gè)CPU都能夠生成一個(gè)到Local RAM和cluster RAM的鏈接。
在目標(biāo)RAM上執(zhí)行LDL指令導(dǎo)致鏈接地址被注冊,同時(shí)設(shè)置鏈接標(biāo)志,并響應(yīng)該指令讀取生成鏈接。
(a)每個(gè)CPU的Local RAM
(b)Cluster RAM
每個(gè)CPU都能夠生成一個(gè)到(a)或(b)的鏈接。
1.3 Success in storing
在生成Link之后,存儲(chǔ)將只響應(yīng)執(zhí)行與生成的鏈路對應(yīng)的STC指令而進(jìn)行,也就說說該存儲(chǔ)地址只能通過STC指令寫入。
1.4 Failure in storing
如果鏈路丟失,即使處理相應(yīng)地址的STC指令,存儲(chǔ)也不會(huì)繼續(xù)。當(dāng)處理與鏈接不對應(yīng)的STC指令時(shí),也不會(huì)繼續(xù)存儲(chǔ)。
個(gè)人理解:Link是一個(gè)抽象概念,通過LDL指令能夠創(chuàng)建一個(gè)link,且每個(gè)CPU只能創(chuàng)建一個(gè)Link,通過STC指令能改寫CPU Link的RAM的值。
1.5 Condition for successful storing
如果滿足以下條件,則判定STC指令為與該鏈路對應(yīng)的地址:
生成鏈接的LDL指令的地址和大小與STC指令的地址和大小相匹配。
1.6 Loss of the link
當(dāng)滿足某些事件或地址條件時(shí),鏈接將丟失。表1顯示了Link loss情況。如果滿足此表中所示的任何條件,則一個(gè)鏈接就會(huì)丟失。
Table 1 Link Loss Conditions
Note: 在Local RAM中,如果執(zhí)行了除STC/CAXI指令以外的存儲(chǔ)指令,則鏈接并不總是丟失。因此,觸使Link Loss的指令程序流是可以不需要的。例如,在接下來的示例代碼中,在使用LDL指令讀取鎖變量后,只有在沒有鎖的情況下才執(zhí)行STC指令,如果鎖已經(jīng)存在(Link已經(jīng)建立)則通過Lock Release對應(yīng)的Link Loss程序流就是不需要的。
也就是說,LDL指令Link成功,STC指令存儲(chǔ)成功(創(chuàng)建一個(gè)Lock),之后的ST等存儲(chǔ)指令用于Link Loss才是有意義的。也就是只有GetSpinlock成功之后才能ReleaseSpinlock.
1.7 示例代碼
通過使用LDL.W和STC.W指令執(zhí)行的自旋鎖的示例代碼如下所示。
一行一行的來分析這段匯編代碼:
MOV lock_adr, r20//lock_adr這個(gè)地址值賦值給r20寄存器,lock_adr可以理解為一個(gè)存在于RAM的全局變量的地址。
LDL.W [r20], r21//以原子操作的方式加載r20寄存器保存的地址所在的值給r21寄存器。這個(gè)指令執(zhí)行完后,r20存儲(chǔ)lock_adr地址值(全局變量的地址),r21保存了lock_adr地址指向的具體變量值(全局變量的值)。Link Generation.
CMP r0, r21//r0寄存器中值與r21寄存器中的值進(jìn)行比較。
Note 1: r0是Zero寄存器,其值永遠(yuǎn)為0.
Note 2: CMP指令的結(jié)果在程序狀態(tài)字寄存器的PSW.Z bit上體現(xiàn),比較的兩個(gè)值如果相等則PSW.Z =1;反之,比較的兩個(gè)值不相等,則PSW.Z = 0.
BNZ lock_wait//如果上一次的cmp結(jié)果不為0,則跳轉(zhuǎn)到lock_wait標(biāo)識(shí)符地址處往下執(zhí)行。
MOV 1, r21//將1賦值給r21寄存器。r21寄存器中保存的值為1.
STC.Wr21, [r20]//將r21寄存器保存的值(1)賦值給r20保存的地址指向的變量。Success in storing.
CMPr0, r21//比較r0(always retains 0)和r21寄存器中保存的值(也就是比較0和1)。
BNZlock_success//如果上一次的cmp結(jié)果不為0,則跳轉(zhuǎn)到lock_success標(biāo)識(shí)符地址處往下執(zhí)行。
Lock_wait: SNOOZE
Note: SNOOZE指令是一種在自旋鎖期間減少總線帶寬使用的指令。該指令完成后,CPU核心進(jìn)入臨時(shí)停止?fàn)顟B(tài),以限制后續(xù)指令的執(zhí)行。程序員可以通過將此指令插入到一個(gè)自旋鎖循環(huán)中,從而避免由于短期重復(fù)鎖定過程而導(dǎo)致的不必要的總線帶寬的使用。
BR Lock//無條件跳轉(zhuǎn)到Lock標(biāo)識(shí)符處
Lock_success://一個(gè)標(biāo)識(shí)符,運(yùn)行到這里表明get spinlock成功,繼續(xù)往下執(zhí)行。
ST.Wr0, 0[r21]//王r21寄存器保存的地址值指向的變量寫入0值。Release spinlock.
2.Spinlock代碼分析
2.1 嘗試獲取Spinlock
準(zhǔn)備獲取Spinlock的時(shí)候,外部就是一個(gè)While循環(huán),直到成功獲取到Spinlock,否則就會(huì)“自旋”。
2.2 釋放Spinlock
釋放Spinlock對應(yīng)的C代碼,只需將標(biāo)識(shí)Spinlock的全局變量賦值為0即可(對應(yīng)ST.W r0, 0[r21]的匯編代碼)。
3.總結(jié)
本文詳細(xì)分析了Spinlock在RH850U2A芯片平臺(tái)上的底層實(shí)現(xiàn),著重需要理解RH850U2A芯片架構(gòu)中的Link概念。Spinlock對應(yīng)的底層兩個(gè)特殊的匯編指令:LDL.W和STC.W. 在C語言環(huán)境下調(diào)用GetSpinlock()的具體實(shí)現(xiàn)也就是調(diào)用OS_LDLW()和STC_STCW()。值得注意的是,Spinlock的底層實(shí)現(xiàn)和具體芯片特性相關(guān),其他芯片平臺(tái)(比如Tricore芯片)的底層具體實(shí)現(xiàn)可能就不一樣了,需要具體分析。
問題:如何理解Spinlok自旋鎖中的”自旋“的含義?
答:“自旋”對應(yīng)底層的SNOOZE指令。當(dāng)前CPU(Core x)執(zhí)行LDL.W沒有建立Link后,CPU執(zhí)行SNOOZE指令暫停一個(gè)機(jī)器周期,隨后再次嘗試去執(zhí)行LDL.W指令,直到建立Link成功(其他CPU釋放Spinlock),這個(gè)過程對應(yīng)“自旋”的含義。
審核編輯:劉清
-
寄存器
+關(guān)注
關(guān)注
31文章
5294瀏覽量
119816 -
RAM
+關(guān)注
關(guān)注
8文章
1354瀏覽量
114444 -
STC
+關(guān)注
關(guān)注
14文章
299瀏覽量
66071 -
PSW
+關(guān)注
關(guān)注
0文章
9瀏覽量
8223 -
自旋鎖
+關(guān)注
關(guān)注
0文章
11瀏覽量
1574
原文標(biāo)題:RH850U2A芯片平臺(tái)Spinlock的底層實(shí)現(xiàn)
文章出處:【微信號(hào):汽車電子嵌入式,微信公眾號(hào):汽車電子嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
評(píng)論