核心的乙個基本原則就是:在中斷或者說原子上下文中,核心不能訪問使用者空間,而且核心是不能睡眠的。也就是說在這種情況下,核心是不能呼叫有可能引起睡眠的任何函式。一般來講原子上下文指的是在中斷或軟中斷中,以及在持有自旋鎖的時候。核心提供了四個巨集來判斷是否處於這幾種情況裡:
#define in_irq() (hardirq_count()) //在處理硬中斷中
#define in_softirq() (softirq_count()) //在處理軟中斷中
#define in_interrupt() (irq_count()) //在處理硬中斷或軟中斷中
#define in_atomic() ((preempt_count() & ~preempt_active) != 0) //包含以上所有情況
這四個巨集所訪問的count都是thread_info->preempt_count。這個變數其實是乙個位掩碼。
最低8位表示搶占計數,通常由spin_lock/spin_unlock修改,或程式設計師強制修改,同時表明核心容許的最大搶占深度是256。
8-15位表示軟中斷計數,通常由local_bh_disable/local_bh_enable修改,同時表明核心容許的最大軟中斷深度是256。
位16-27是硬中斷計數,通常由enter_irq/exit_irq修改,同時表明核心容許的最大硬中斷深度是4096。
第28位是preempt_active標誌。用**表示就是:
preempt_mask: 0x000000ff
softirq_mask: 0x0000ff00
hardirq_mask: 0x0fff0000
凡是上面4個巨集返回1得到地方都是原子上下文,是不容許核心訪問使用者空間,不容許核心睡眠的,不容許呼叫任何可能引起睡眠的函式。而且代表thread_info->preempt_count不是0,這就告訴核心,在這裡面搶占被禁用。
但是,對於in_atomic()來說,在啟用搶占的情況下,它工作的很好,可以告訴核心目前是否持有自旋鎖,是否禁用搶占等。但是,在沒有啟用搶占的情況下,spin_lock根本不修改preempt_count,所以即使核心呼叫了spin_lock,持有了自旋鎖,in_atomic()仍然會返回0,錯誤的告訴核心目前在非原子上下文中。所以凡是依賴in_atomic()來判斷是否在原子上下文的**,在禁搶占的情況下都是有問題的。
原子上下文
核心的乙個基本原則就是 在中斷或者說原子上下文中,核心不能訪問使用者空間,而且核心是不能睡眠的。也就是說在這種情況下,核心是不能呼叫有可能引起睡眠的任何函式。一般來講原子上下文指的是在中斷或軟中斷中,以及在持有自旋鎖的時候。核心提供了四個巨集來判斷是否處於這幾種情況裡 define in irq h...
程序上下文 中斷上下文及原子上下文
談論程序上下文 中斷上下文 原子上下文之前,有必要討論下兩個概念 a 上下文 上下文是從英文context翻譯過來,指的是一種環境。相對於程序而言,就是程序執行時的環境 具體來說就是各個變數和資料,包括所有的暫存器變數 程序開啟的檔案 記憶體資訊等。b 原子 原子 atom 本意是 不能被進一步分割...
程序上下文和中斷上下文 原子上下文的區別
核心空間和使用者空間是現代作業系統的兩種工作模式,核心模組執行在核心空間,而 使用者態應用程式執行在使用者空間。它們代表不同的級別,而對系統資源具有不同的訪問許可權。核心模組執行在最高端別 核心態 這個級下所有的操作都受系統信 任,而應用程式執行在較低級別 使用者態 在這個級別,處理器控制著對硬體的...