日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Symmetric multiprocessing(SMP)下的spinlock

發布時間:2024/4/18 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Symmetric multiprocessing(SMP)下的spinlock 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

現在的計算機都是多核對稱的cpu處理器,本文通過liunx內核2.6.0代碼來分析在多核處理器下,如何使用自旋鎖和搶占來進行高效的內核運轉。
如果正在內核中運行著的任務此時可以搶占另外一個內核執行的任務,比如說有一個優先級很高的任務想去搶占內核中正在運行的任務,在linux2.6之前是沒有實現的。
在2.6版本的內核中,加入了搶占相關的信息,在preempt.h頭文件里,定義了一個preempt_count如果這個count大于零表示不可以被搶占,如果等于零,表示可以被搶占。

#define preempt_count() (current_thread_info()->preempt_count)//核心變量,每一個任務的線程信息里都有這個值 //對這個變量進行加減操作 #define inc_preempt_count() \ do { \preempt_count()++; \ } while (0)#define dec_preempt_count() \ do { \preempt_count()--; \ } while (0)#ifdef CONFIG_PREEMPT //搶占動作,在別的文件中實現,所以是extern extern void preempt_schedule(void); //禁用就是讓它加1 #define preempt_disable() \ do { \inc_preempt_count(); \barrier(); \//這是一個編譯器屏障 } while (0)#define preempt_enable_no_resched() \ do { \barrier(); \dec_preempt_count(); \ } while (0)#define preempt_check_resched() \ do { \if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \preempt_schedule(); \ } while (0)#define preempt_enable() \ do { \preempt_enable_no_resched(); \preempt_check_resched(); \ } while (0)#else#define preempt_disable() do { } while (0) #define preempt_enable_no_resched() do { } while (0) #define preempt_enable() do { } while (0) #define preempt_check_resched() do { } while (0)#endif

上面的文件可以看出這個preempt變量的重要性。
隨后在自旋鎖的實戰中,用到了這些變量,在linux/spinlock.h文件里可以看到如下的關鍵代碼:

#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPT)//如果在smp下 void __preempt_spin_lock(spinlock_t *lock);//增加的核心函數 void __preempt_write_lock(rwlock_t *lock);//增加的核心函數#define spin_lock(lock) \ do { \preempt_disable(); \//先禁止搶占if (unlikely(!_raw_spin_trylock(lock))) \__preempt_spin_lock(lock); \//如果嘗試上鎖失敗,就進入這個核心方法 } while (0)#define write_lock(lock) \ do { \preempt_disable(); \//先禁止搶占if (unlikely(!_raw_write_trylock(lock))) \__preempt_write_lock(lock); \ } while (0)#else//沒有多對稱處理器就不會有上面那兩個核心方法 #define spin_lock(lock) \ do { \preempt_disable(); \_raw_spin_lock(lock); \ } while(0)#define write_lock(lock) \ do { \preempt_disable(); \_raw_write_lock(lock); \ } while(0) #endif

在kernal/sched.c文件中有這兩個獨特的函數實現:

void __preempt_spin_lock(spinlock_t *lock) {if (preempt_count() > 1) {//這里什么時候會大于一可以看看下面的解釋_raw_spin_lock(lock);//直接去自旋獲得鎖return;}//如果小于等于1才會進來do {preempt_enable();//開啟讓別的任務可以搶占該任務,這里當然就是當前的這一個cpu里別的任務可以繼續進來進行,而不會因為這個任務而卡死在這里while (spin_is_locked(lock))cpu_relax();//空循環去判斷是否上鎖,如果發現可以搶占鎖了,那么就會立即禁止搶占,再去獲得鎖preempt_disable();} while (!_raw_spin_trylock(lock)); }void __preempt_write_lock(rwlock_t *lock) {if (preempt_count() > 1) {_raw_write_lock(lock);return;}do {preempt_enable();while (rwlock_is_locked(lock))cpu_relax();preempt_disable();} while (!_raw_write_trylock(lock)); }

什么時候會preempt_count() > 1呢,也就是同一個任務又獲得了這把鎖,那么就會立即去spin_lock,此時preempt_count就會大于1,因為spin_lock先會disable,而此時該任務在發現可以獲得鎖的時候,又disable了一次,此時不會讓這個任務再去enable了,因為此時已經大于1了,再減一也不是0,本地cpu的其他任務還是搶占不到當前cpu讓它工作,所以這也說明了禁止搶占兩次。

總結

以上是生活随笔為你收集整理的Symmetric multiprocessing(SMP)下的spinlock的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。