void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
用于结束wait queue 之后的清理工作,首先将当前函数的状态设置为TASK_RUNNING,如果第二个形参
wait->task_list 不为null的话,则将wait->task_list 做置null,并重新对wait->task_list进行初始化
其用法之前已经博文展示过了
其源码分析如下:
void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
{
unsigned long flags;
//将当前进程的状态设置为TASK_RUNNING
__set_current_state(TASK_RUNNING);
/*
* We can check for list emptiness outside the lock
* IFF:
* - we use the "careful" check that verifies both
* the next and prev pointers, so that there cannot
* be any half-pending updates in progress on other
* CPU's that we haven't seen yet (and that might
* still change the stack area.
* and
* - all other users take the lock (ie we can only
* have _one_ other CPU that looks at or modifies
* the list).
*/
//wait->task_list 不为null的话,则调用list_del_init删除这个list上的entry,并重新初始化
if (!list_empty_careful(&wait->task_list)) {
spin_lock_irqsave(&q->lock, flags);
list_del_init(&wait->task_list);
spin_unlock_irqrestore(&q->lock, flags);
}
}
这里用list_empty_careful 来判断list是否为null。这个函数和list_empty相比检测更严格一点,
个人感觉list_empty 适用用单向链表和list_empty_careful 适用于双向链表
static inline int list_empty(const struct list_head *head)
{
return READ_ONCE(head->next) == head;
}
通过code 对比很容易看出区别.
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
进程调度API之finish_wait
最新推荐文章于 2022-10-18 17:02:49 发布