天天看點

記憶體模型與同步原語 - 4 在設計同步原語時,我們在考慮什麼?

互斥是指對共享資源的排他性通路,同步是指對程序執行的先後順序作出妥善安排

Linux 核心中的各種鎖機制實際上都是實作“互斥”的語義

design principle of locking

parallesim

在讨論各種鎖機制之前,有必要讨論系統的并行度,即有哪些潛在的競争場景

  1. 中斷上下文與程序上下文對共享資源的通路,由于中斷是異步進行的,因而中斷與程序是并發執行的,當中斷上下文與程序上下文同時對共享資源進行通路時,就有可能形成競争
  2. 在 UP 與 SMP 系統中,當處理器是可搶占的時,由于可搶占的特性,同一個處理器内程序與程序間是并發執行的
  3. 在 SMP 系統中,多處理器間的程序是嚴格意義上的并發執行的

parallesim from preemption

在單處理器上,程序之間的搶占是并行度的一大來源,為了排除程序搶占帶來的并行度,在鎖機制的實作過程中必須關閉搶占

parallesim from SMP

在 SMP 系統中,多處理器之間是嚴格并發執行的

目前核心中大部分鎖機制使用 counter based locking 來排除多處理器之間的并行度,其原理是維護一個整型資料類型的 counter 計數器,計數器的值就表示可用資源的份數,在申請占用資源的時候計數器就加 1,在申請釋放資源的時候計數器就減 1

counter based 的鎖機制在實作時都需要考慮 atomic 與 barrier 兩個次元

atomic

首先,counter based 的鎖機制的核心都是整型資料類型的 counter 計數器,需要保證對計數的操作是 atomic 的

現代處理器架構一般都保證對整型資料類型的 load 或 store 操作原生是 atomic 的,但是鎖機制中大量涉及的是 add/sub 即 RMW (Read-Modify-Write) 操作,但是處理器架構一般不能保證 RMW (Read-Modify-Write) 操作原生是 atomic 的

  • x86 架構下使用 LOCK 指令來實作 atomic RMW (read-modify-write)
  • ARM 架構下提供 LDREX/STREX 指令來實作 atomic RMW (read-modify-write)
acquire/release barrier

隻有 atomic RMW (read-modify-write) 還不夠,因為 memory reordering 可能會将 lock 操作之後的記憶體通路指令重排到 lock 操作之前執行

update counter
---------------------
LOCK
---------------------
critical area           

也有可能将 unlock 操作之前的記憶體通路指令重排到 unlock 操作之後執行

critical area
---------------------
UNLOCK
---------------------
update counter           

因而 counter based 的鎖機制還需要實作 acquire/release 語義,進而確定 lock 操作之後的記憶體通路指令不會重排到 lock 操作之前執行

update counter
---------------------
read acquire (LOCK)
---------------------
critical area stay below the line           

unlock 操作之前的記憶體通路指令不會重排到 unlock 操作之後執行

critical area stay above the line
---------------------
write release (UNLOCK)
---------------------
update counter           

這就需要在 lock 操作的最後調用 acquire barrier,在 unlock 操作的最開始調用 release barrier,進而確定 lock/unlock 之間的記憶體通路指令一定位于 lock/unlock 之間

x86 架構下由于隻存在 StoreLoad reorder,因而天生滿足 acquire/release 語義,因而 x86 架構下以上這兩個 barrier 的定義都為空

aarch64 架構下則使用 dmb 指令實作 acquire/release 語義

parallesim from IRQ

以上 atomic、barrier、preemption 三個次元實作的鎖機制,不是中斷安全的,即并不能排除中斷帶來的并行度

如果鎖機制需要保護的共享資源不會被中斷處理程式通路,即隻是在 process context 之間共享,那麼以上三個次元 atomic、barrier、preemption 實作的鎖機制就完全夠用了

而如果共享資源還會被中斷處理程式通路,也就是共享資源實際上是在 process context 和 interrupt context 之間共享,那麼由 process context 這一方發起的上鎖的過程中,還必須關閉全局中斷

繼續閱讀