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