x86平台原子操作API的實現原理

2021-06-29 02:30:16 字數 2623 閱讀 8355

原子操作的意義

對於軟體來說,**的行為必須是確定的,就是說通過手工分析**也能預知執行結果。但是程式在併發和並行時,因為作業系統任務排程的不確定性和多處理器之間的相互影響,導致**執行的結果無法預知。這種情況下,只有強制保證某些指令的執行是原子操作,**執行結果才是可預知的,原子操作也是多工作業系統設計的基石。正確的使用原子操作,可以避免多工導致的髒資料,保證**行為的正確。下面通過一段**說明為什麼程式在併發和並行時需要原子操作。

#include #include #include #include int g_count1;

volatile long g_count2;

handle h_event;

unsigned int callback func_callback(void *context);

int main(const int argc, const char *argv)

unsigned int callback func_callback(void *context)

return 0;

}

輸出結果 g_count1=16627 g_count2=20000 可以看到g_count1的結果小於20000。可以看下反彙編來分析:

while (count-- > 0)

00fb144c  mov         eax,dword ptr [count] 

00fb144f  mov         dword ptr [ebp-0d0h],eax 

00fb1455  mov         ecx,dword ptr [count] 

00fb1458  sub         ecx,1 

00fb145b  mov         dword ptr [count],ecx 

00fb145e  cmp         dword ptr [ebp-0d0h],0 

00fb1465  jle         func_callback+63h (0fb1473h) 

00fb1467  mov         dword ptr [ebp-0d4h],1 

00fb1471  jmp         func_callback+6dh (0fb147dh) 

00fb1473  mov         dword ptr [ebp-0d4h],0 

00fb147d  cmp         dword ptr [ebp-0d4h],0 

00fb1484  je          func_callback+93h (0fb14a3h) 

00fb14a1  jmp         func_callback+3ch (0fb144ch) 

return 0;

00fb14a3  xor         eax,eax  }

可以看到與g_count1++語句對應的彙編指令是由加操作和賦值操作兩條指令完成的,在這兩條指令之間可能發生任務切換。如果執行緒1執行加操作指令後,當前執行緒被切換到執行緒2,執行緒2重新執行取g_count1原始值的操作,然後切換回到執行緒1時,eax暫存器又被放入了g_count1的原始值,執行緒1的加1操作等於沒有做。而作業系統提供的原子加1操作的api是一條指令,在指令執行期間不會發生任務切換,並且因為該指令有lock字首,在多處理器架構中也不會受到其他處理器的影響。

原子操作/多工/鎖的一些基本概念

1 任務切換是用中斷機制觸發的,想發生任務切換必須向處理器通知一次中斷的發生;

2 任務切換只能發生在指令邊緣,就是說兩條指令執行的間隙可能會發生任務切換,一條指令執行期間不會發生任務切換;

3 原子操作就是不可中斷的一系列操作,如果被中斷就會引起執行結果和預期不符;

4 單處理器架構下,一條指令的執行是原子操作;多處理器架構下,即使是一條指令執行期間也會受到其他處理器的干擾,導致指令執行結果錯誤。lock指令字首的作用就是獨佔匯流排,保證在多處理器架構下一條指令的執行是原子操作。該指令字首的實現必須是物理的,由處理器提供,軟體無法實現。作業系統基於lock指令字首封裝一系列原子操作的api供上層應用使用;

單處理器架構下原子操作的實現

1 關中斷

2 執行一系列指令,執行期間不會發生任務切換

3 開中斷

多處理器架構下的原子操作的實現

在需要原子操作的指令前附加lock指令字首,intel x86只有指定的幾個指令才可以附加lock指令字首。作業系統把這些附加了lock指令字首的指令包裝後,做成多種原子操作api**用使用。

lock指令字首的物理表現

當某條指令被加上lock指令字首時,該指令在執行前,會把處理器的#hlock引腳拉低,該引腳被拉低導致匯流排被鎖,其他處理器不能訪問匯流排,直到指令執行完畢,處理器的#hlock引腳恢復以後,匯流排的訪問權才被釋放。

原子操作的缺點

獨佔匯流排,會影響處理器的效率。但是原子操作是保證多工軟體的執行正確性的最小粒度,別無選擇。



強健x86平台

最近,聯想的企業級業務頗受關注。雖然與收購ibm x86伺服器業務以及摩托羅拉移動這些大動作相比,聯想宣布與賽門鐵克合作也許不夠勁爆,但從完善聯想企業級解決方案的角度來看,聯想與賽門鐵克的戰略合作同樣舉足輕重。聯想it管理服務及企業級服務業務部總經理林林表示,雙方將基於x86硬體,為中國客戶提供端到...

X86平台和ARM平台

x86和arm都是指cpu的核心。桌面電腦,膝上型電腦中使用的intel amd處理器,就是x86處理器。arm是一家英國的處理器設計公司,其設計的處理器採用了arm核心。arm指令集少,電路規模小,功耗低,發熱低,非常適合於嵌入式 可攜式電子產品,如手機 平板,以及工業嵌入式等。32位系統需要x8...

x86 平台kernel config新舊編譯方法

在86平台 config的配置檔案 arch x86 configs x86 64 defconfig 這個配置檔案是原始的kernel配置檔案 如果自己有一套新的config,需要編譯 第一步 將自己的config 拷貝到 arch x86 configs x86 64 defconfig 然後執...