进程调度API之finish_wait

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);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值