免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1322 | 回复: 0
打印 上一主题 下一主题

[学习分享] Linux驱动>等待队列笔记 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-03-26 21:49 |只看该作者 |倒序浏览
在驱动中因某条件不满足无法为系统调用提供服务时,驱动应采取的策略是将系统调用阻塞,等条件满足之后再返回。那么如何实现阻塞,这就要用内核提供的休眠机制了,即驱动中可以定义多种条件(每种条件对应一个等待队列,每个等待队列需要一个等待队列头),当应用程序使用一些系统调用时,驱动先检查是否可提供服务,当无法提供服务时,将进程加入相应的等待队列头,然后睡眠。

有系统调用遇到驱动无法服务时便调用相关的等待函数:
wait_event(wq, condition)
wait_event_timeout(wq, condition, timeout)
wait_event_interruptible(wq, condition)
wait_event_interruptible_timeout(wq, condition, timeout)
调用之后,此进程因条件不满足而睡眠了,必须由中断或其它进程在修改条件为真之后调用**函数:
wake_up(x)
wake_up_all(x)
wake_up_interruptible(x)
wake_up_interruptible_all(x)
调用之后,内核调度器继续调度该进程(wake_up里到底是怎样做的暂时还没理清头绪,有人知道麻烦告知)

等待函数的实现分析:
wait_event>
        __wait_event>
do {/*把当前进程信息填入等待队列项*/                        \
        DEFINE_WAIT(__wait);                                                \
                                                                        \
        for (; {/*把等待队列项加入等待队列头链表,并设置进程状态*/        \
                prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);        \
                if (condition)                                                \
                        break;                                                \
                schedule();                                                \
        }                                                                \
        finish_wait(&wq, &__wait);                                        \
} while (0)
其中的细节还没搞清楚,麻烦大神告知


**函数的实现分析:
__wake_up>
        __wake_up_common>
//遍历整个等待队列头链表
list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
                unsigned flags = curr->flags;

                if (curr->func(curr, mode, wake_flags, key) &&
                                (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
                        break;
        }
其中的细节还没搞清楚,麻烦大神告知



驱动程序只有1个条件时的示意模板:
static int xxx_read(struct file *filp, char __user *buff,size_t count, loff_t *offp)
{
        unsigned long err;
        if (条件1) {
                if (filp->f_flags & O_NONBLOCK)
                        return -EAGAIN;
                else
                        wait_event_interruptible(等待队列头地址, 条件1);//此处睡眠
        }

        ……//条件成立后才能执行到此处,写驱动正常的功能

        return ……;
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP