macro : might_sleep
用來檢測目前process可否sleep,不知道這樣的解釋是否不當。
從code中挖出此macro
#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
void __might_sleep(char *file, int line);
# define might_sleep() \
do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0)
#else
# define might_sleep() do { might_resched(); } while (0)
#endif
看來是紅色的部分,其中會在呼叫might_reshed()
在挖出might_reshed會發現他也是個macro,如下:
#ifdef CONFIG_PREEMPT_VOLUNTARY
extern int _cond_resched(void);
# define might_resched() _cond_resched()
#else
# define might_resched() do { } while (0)
#endif
其中might_reshed() = _cond_resched(),在追入_cond_reshed()
int __sched _cond_resched(void)
{
if (need_resched() && !(preempt_count() & PREEMPT_ACTIVE) &&
system_state == SYSTEM_RUNNING) {
__cond_resched();
return 1;
}
return 0;
}
先看紅色need_reshed()的內容如下,他會去check TIF_NEED_RESHED這個flag
static inline int need_resched(void)
{
return unlikely(test_thread_flag(TIF_NEED_RESCHED));
}
若TIF_NEED_RESCHED為rescheduling necessary則表示目前的process允許核心做scheduling,代表可以被插隊。
第二個看黃色的 !(preempt_count() & PREEMPT_ACTIVE),preempt_count = 0表示process可以被插隊,反之則不可。利用preempt_count和PREEMPT_ACTIVE取and後的結果做反向得到該process可否被插隊。
最後的system_state則是單純的確定系統狀態是否處於running。
綜合以上三個部分若結果成立,則執行__cond_resched();
__cond_resched()內部如下:
static void __cond_resched(void)
{
#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
__might_sleep(__FILE__, __LINE__);
#endif
do {
add_preempt_count(PREEMPT_ACTIVE);
schedule();
sub_preempt_count(PREEMPT_ACTIVE);
} while (need_resched());
}
此API會呼叫 schedule()讓核心重新排程。
另外關於process中TIF_NEED_RESCHED這個flag的設定我繼續研究中。
留言
張貼留言