windows庫已經提供了旋轉鎖的函式,為什麼我們還要自己實現呢?因為彙編快啊!
加鎖
先定義巨集:
#define interlocked_increment(a,b) \
__asm mov eax,0 \
__asm mov ecx,a \
__asm mov edx,1 \
__asm lock cmpxchg dword ptr [ecx],edx \
__asm mov b,eax
a代表臨界資源當前是否被其他執行緒占用,只有0和1兩種取值;b表示是否需要自旋等待,也只有0和1兩種取值。
最關鍵的是cmpxchg句,cmpxchg指令將累加器al/ax/eax/rax中的值與首運算元(目的運算元)比較,如果相等,第2運算元(源運算元)的值裝載到首運算元,zf置1;如果不等, 首運算元的值裝載到al/ax/eax/rax並將zf清0。
我們這裡不關心zf,總結而言:
當a為0時,首運算元[ecx]與eax相等(都為0),於是將源運算元edx(值為1)裝載到首運算元,即將a置為1,以將其他執行緒拒之門外,最後將b置為0,表示資源搶占成功;
當a為1時,首運算元[ecx]與eax不相等,於是首運算元[ecx]裝載到eax,eax值變為1,最後b被置為1,表示資源尚未搶占成功。
光有interlocked_increment(a,b)當然還不夠,需要做如下封裝:
void spinlockex(long *systemspinlocksection)
}
如果systemspinlocksection為0,跑上來k就被置為0,那麼while(k)就被跳過,我們已經搶占到了資源,就不需要自旋等待了;
如果systemspinlocksection為1,那麼k就被置為1,自旋等待,直到突然有一天,systemspinlocksection成了0,那麼k變成0就可以跳出迴圈了。
解鎖
也先來段巨集:
#define interlocked_decrement(a) \
__asm mov eax,0ffffffffh \
__asm mov ecx,a \
__asm lock xadd dword ptr [ecx],eax
解鎖的處理就比加鎖簡單多了,xadd指令將eax累加到[ecx]中,0ffffffffh的十進位制值就是-1,於是interlocked_decrement(a)就是簡單地將a遞減,即由1置為0。
介面封裝如下:
void spinunlockex(long *systemspinlocksection)
大功告成~
Linux系統 gdb彙編級除錯C語言程式
彙編級除錯 1.進入gdb gdb progarm 2.對程式打斷點 break main c語言級的斷點,break main 偏移量 彙編級斷點 3.r 執行程式 4.檢視記憶體 x 5xw 0xbffff0a4 檢視五個資料,以十六進製制 x,o,d,s,s為以字串形式顯示 乙個資料長度為四 ...
java開發系統核心 實現程序優先順序佇列
前幾節,我們實現了程序的排程,並給每個程序賦予相應優先順序,優先順序高的程序,能夠得到更多的cpu時間。但在演示時,我們發現乙個問題,就是,當程序傳送切換時,滑鼠鍵盤的響應會被卡死,這是因為響應滑鼠鍵盤事件的程序被調到後台,無法獲得cpu執行時間,從而不能處理滑鼠或鍵盤事件。這種情況對使用者來說,是...
用執行緒和互斥鎖實現的簡單的賣票系統
include include include include include int ticket 100 票 互斥鎖 pthread mutex t mutex 賣票執行緒 void sale ticket void v printf 視窗 d 賣票了一張票 d n window,ticket ...