引述自:
核心的乙個基本原則就是:在中斷或者說原子上下文中,核心不能訪問使用者空間,而且核心是不能睡眠的。也就是說在這種情況下,核心是不能呼叫有可能引起睡眠的任何函式。一般來講原子上下文指的是在中斷或軟中斷中,以及在持有自旋鎖的時候。核心提供了四個巨集來判斷是否處於這幾種情況裡:#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...
核心中的原子上下文
核心的乙個基本原則就是 在中斷或者說原子上下文中,核心不能訪問使用者空間,而且核心是不能睡眠的。也就是說在這種情況下,核心是不能呼叫有可能引起睡眠的任何函式。一般來講原子上下文指的是在中斷或軟中斷中,以及在持有自旋鎖的時候。核心提供了四個巨集來判斷是否處於這幾種情況裡 define in irq h...
原子上下文
核心的乙個基本原則就是 在中斷或者說原子上下文中,核心不能訪問使用者空間,而且核心是不能睡眠的。也就是說在這種情況下,核心是不能呼叫有可能引起睡眠的任何函式。一般來講原子上下文指的是在中斷或軟中斷中,以及在持有自旋鎖的時候。核心提供了四個巨集來判斷是否處於這幾種情況裡 define in irq h...