最近看了swait.c (simple wait queue)的源码,尝试自己实现一下
1、背景
要实现以下目标:
(1) 不满足等待条件一直等待,不可被打断
(2) 并发正确的等待队列
(3) timeout机制
kernel 5.15
2、实现
(1) 先来实现目标1 2
//队列头和队列节点
struct swait_queue_head {
raw_spinlock_t lock;
struct list_head task_list;
};
struct swait_queue {
struct task_struct *task;
struct list_head task_list;
};
//无需返回值
void swait_event_uninterruptable(swait_queue_head *wq, func_t condition) {
swait_queue __wait;
spin_lock(wq->lock);
list_add(__wait.task_list, &wq->task_list);
spin_unlock(wq->lock);
for (;;) {
if(condition)
break;
//设置线程状态,每次被唤醒都需要重新设置
set_current_state()
scheduler();
}
spin_lock(wq->lock);
list_del(__wait.task_list);
spin_unlock(wq->lock);
}
(2) timeout实现,目标3
//需要返回值确定是成功还是timeout
// 0 timeout
// !0 success
long swait_event_uninterruptable(swait_queue_head *wq, func_t condition, long timeout) {
swait_queue __wait;
long __ret = timeout;
spin_lock(wq->lock);
list_add(&__wait.task_list, &wq->task_list);
spin_unlock(wq->lock);
for (;;) {
//防止condition = true && __ret == 0 返回值不对的情况
if(condition && !__ret)
__ret = 1;
//等待条件为true 或者 超时
if(condition || !__ret) {
break;
}
//设置线程状态,每次被唤醒都需要重新设置
set_current_state()
//返回到timeout还有多少时间
__ret = scheduler_timeout(__ret);
}
spin_lock(wq->lock);
list_del(&__wait.task_list);
spin_unlock(wq->lock);
return __ret;
}
3、 todo
(1) swait还有
interruptable(涉及信号)
exclusive
两个维度,有兴趣再研究吧
源码里用一个宏实现了所有维度的函数,抽象的比较好
(2) 有simple wait queue 就必然有真正的wait queue,实现肯定比这个复杂,swait.c开头的注释里也说了