From aad5b1e2283ef84665a3c8ad8209c960989570f6 Mon Sep 17 00:00:00 2001 From: "ithink.chan" Date: Sun, 26 Apr 2020 11:10:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20Linux=20Kernel=20=E7=AD=89?= =?UTF-8?q?=E5=BE=85=E9=98=9F=E5=88=97.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ithink.chan --- .../Linux/Kernel/API/Linux_Kernel_等待队列.md | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 Software/Development/OperatingSystem/Linux/Kernel/API/Linux_Kernel_等待队列.md diff --git a/Software/Development/OperatingSystem/Linux/Kernel/API/Linux_Kernel_等待队列.md b/Software/Development/OperatingSystem/Linux/Kernel/API/Linux_Kernel_等待队列.md new file mode 100644 index 0000000..f23a41a --- /dev/null +++ b/Software/Development/OperatingSystem/Linux/Kernel/API/Linux_Kernel_等待队列.md @@ -0,0 +1,107 @@ +# Linux Kernel 等待队列 + +## wait_event_interruptible_timeout 函数 + +**函数原型:** + +```sh +#define wait_event_interruptible_timeout(wq_head, condition, timeout) \ +({ \ +  long __ret = timeout; \ +  might_sleep(); \ +  if (!___wait_cond_timeout(condition)) \ +    __ret = __wait_event_interruptible_timeout(wq_head, \ +                  condition, timeout); \ +    __ret; \ +}) +``` + +**说明:** + +睡眠到 condition 为真,或超时。支持可中断的睡眠,意味着可以发送信号给睡眠的进程,进程会对信号进行响应。 + +**参数:** + +wq:要等待的等待队列 + +condition:等待事件发生的条件(一个C表达式 ) + +timeout:超时时间 + +**返回值:** + +当返回值大于 0 时,表示返回的是剩余的时间(以 jiffy为单位),条件满足,也就是还未超时,条件已经达成了,被唤醒了。 + +当返回值为 0 时,表示超时,自动唤醒,此时根据情况进行错误处理吧。 + +## wake_up_interruptible 函数 + +**函数原型:** + +```cpp +void wake_up_interruptible (wait_queue_head_t *q); +``` + +**说明:** + +唤醒 q 指定的注册在等待队列上的进程。该函数不能直接的立即唤醒进程,而是由调度程序转换上下文,调整为可运行状态。 + +**参数:** + +q:等待队列变量指针。 + +**返回值:** + +无 + +## wake_up_interruptible + +## wake_up_interruptible_nr + +## wake_up_interruptible_all + +## wake_up_interruptible_sync + +## 示例 + +```cpp +wait_queue_head_t wq; +uint8_t condition = 0; +uint64_t timeout_jf = 500; + +/** + * @brief 初始化函数 + * @return + */ +void init_func() +{ + init_waitqueue_head(&wq); +} + +/** + * @brief 谋过程调用中需要等待中断 + * @return 成功或失败 + */ +ssize_t xxx_func() +{ + int32_t err; + ssize_t ret = 0; + + err = wait_event_interruptible_timeout(wq, (condition== 1), timeout_jf); + if (err == 0) + ret = -ETIMEDOUT; + else if (err < 0) + ret = -EINTR; + + return ret; +} + +/** + * @brief 中断处理函数 + */ +void irq_handle() +{ + condition = 1U; + wake_up_interruptible(&wq); +} +```