linux 位操做

atomic_t 類型在進行整數算術時是不錯的. 可是, 它沒法工做的好, 當你須要以原子方 式操做單個位時. 爲此, 內核提供了一套函數來原子地修改或測試單個位. 由於整個操做 在單步內發生, 沒有中斷(或者其餘處理器)能干擾.ide

 

原子位操做很是快, 由於它們使用單個機器指令來進行操做, 而在任什麼時候候低層平臺作的 時候不用禁止中斷. 函數是體系依賴的而且在 <asm/bitops.h> 中聲明. 它們保證是原子 的, 即使在 SMP 計算機上, 而且對於跨處理器保持一致是有用的.函數

 

不幸的是, 鍵入這些函數中的數據也是體系依賴的. nr 參數(描述要操做哪一個位)經常定 義爲 int, 可是在幾個體系中是 unsigned long. 要修改的地址經常是一個 unsigned long 指針, 可是幾個體系使用 void * 代替.測試

 

各類位操做是:atom

 

void set_bit(nr, void *addr);指針

 

設置第 nr 位在 addr 指向的數據項中. void clear_bit(nr, void *addr);調試

清除指定位在 addr 處的無符號長型數據. 它的語義與 set_bit 的相反. void change_bit(nr, void *addr);源碼

翻轉這個位. test_bit(nr, void *addr);it

這個函數是惟一一個不須要是原子的位操做; 它簡單地返回這個位的當前值.asm

 

int test_and_set_bit(nr, void *addr); int test_and_clear_bit(nr, void *addr); int test_and_change_bit(nr, void *addr);class

 

原子地動做如同前面列出的, 除了它們還返回這個位之前的值.

 

 

當這些函數用來存取和修改一個共享的標誌, 除了調用它們不用作任何事; 它們以原子發 生進行它們的操做. 使用位操做來管理一個控制存取一個共享變量的鎖變量, 另外一方面, 是有點複雜而且應該有個例子. 大部分現代的代碼不以這種方法來使用位操做, 可是象下 面的代碼仍然在內核中存在.

 

一段須要存取一個共享數據項的代碼試圖原子地請求一個鎖, 使用 test_and_set_bit 或 者 test_and_clear_bit. 一般的實現展現在這裏; 它假定鎖是在地址 addr 的 nr 位. 它還假定當鎖空閒是這個位是 0, 忙爲 非零.

 

/* try to set lock */

while (test_and_set_bit(nr, addr) != 0) wait_for_a_while();

 

/* do your work */

 

/* release lock, and check... */

if (test_and_clear_bit(nr, addr) == 0) something_went_wrong(); /* already released: error */

 

 

若是你通讀內核源碼, 你會發現象這個例子的代碼. 可是, 最好在新代碼中使用自旋鎖; 自旋鎖很好地調試過, 它們處理問題如同中斷和內核搶佔, 而且別人讀你代碼時沒必要努力 理解你在作什麼.

相關文章
相關標籤/搜索