vxWorks smp架構下互斥與同步
UP中關中斷,掛起任務等對臨界區保護的做法,在SMP中不再適用,因為它阻礙了同時執行理念,降低了CPU利用率。主要不同是在taskLock與intLock上。SMP提供四中同步與互斥鎖:
- 任務與中斷級的spinLock
- 任務與中斷級CPU指定
- 原子操作
- 記憶體屏障
1、spinLock的互斥與同步
UP(單核)中的訊號量用於任務的互斥與同步在SMP中同樣適用,而spinLock則是SMP中用來替換taskLock與intLock的函式。spinLock也稱自旋鎖具備全記憶體屏障的屬性,也就是要在臨界區內的記憶體讀寫操作可以按順序執行而不受多CPU影響,保證更新順序。spinLock使用FIFO處理加鎖請求,避免了死鎖。spinLock是被核佔用,而不任務佔用,會造成核忙等,增加系統延遲。如下圖所示
spinLock分為中斷級與任務級。
中斷級spinLock:
- 關閉本地核的中斷。
- 關閉本地核任務搶佔。
- 其它核的任務搶佔與中斷不受影響。
任務級spinLock
- 關閉本地核任務搶佔。
- 其它核任務與中斷不受影響。
對於中斷級的spinLock分為確定的spinLock與非確定的spinLock。
對於確定性的spinLock,是保證了公平性,誰先請求誰先得到。而非確定性spinLock則是誰先搶到誰先得到。
上表是確定性spinLock使用的api,我們也可以使用SPIN_LOCK_ISR_DECL靜態初始化一個isr_spinLock。
對於非確定性spinLock有一個好的中斷延遲,因為在等待獲得spinLock期間,中斷不被鎖定。
任務級spinLock相當於替換了單核的taskLock,但是有個重要提示,那就它只鎖定本地CPU任務搶佔。
最後還有一個spinLock的除錯版本,當呼叫spinLock重啟後會記錄下相關資訊。需要新增INCLUDE_SPINLOCK_DEBUG元件,請查閱vxworks api文件。
2、任務與中斷的CPU指定
CPU指定的互斥必須使用CPU親和性將ISR或者任務繫結到指定CPU才有效,這是使用任務與中斷CPU指定互斥的前提。
3、記憶體屏障
記憶體屏障是為了強制CPU進行順序記憶體操作,不亂順執行。
上面這個例子,core1在輪詢flag,當core2設定flag=1時,core1同步列印value。在core2上,flags是最後設定的,但是core2可能亂序執行value=2;flag=1的語句,造成core1列印value=0;
這裡我們加上寫屏障,意思是屏障前的寫操作全部完成再執行flag=1的操作。
記憶體屏障分為:
4、原子操作
原子操作是針對記憶體中單項資料進行的,這些操作不被中斷及任務打斷。原子操作在進行簡單資料更新時,可以用來替換spinLock,分為arithmetic, logical, read/write, compare/swap四個邏輯組。原子操作需要記憶體對齊。
最後說一下vxCasp這個原子操作,它是一個複合操作。意思就是對比和交換資料,但是
只有當目標和比較值相等才交換資料。
5、CPU資訊與管理
最後補充一點CPU資訊與管理的資訊。
CPU空閒狀態:
系統空閒狀態:
KernelIsSystemIdle,只能在isr中呼叫,在task中呼叫永遠返回false。
CPU使用: