From d62826bee2075224fcb525b36bd883aa2fa184d7 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Wed, 7 Jun 2017 08:00:28 +0100 Subject: [PATCH] bak wait queue --- kernel_module/wait_queue.c | 15 ++++++- kernel_module/wait_queue2.c | 79 +++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 kernel_module/wait_queue2.c diff --git a/kernel_module/wait_queue.c b/kernel_module/wait_queue.c index c4a6108..f446994 100644 --- a/kernel_module/wait_queue.c +++ b/kernel_module/wait_queue.c @@ -3,6 +3,18 @@ if (!cond) sleep_until_event + +Outcome: + + 1 0 + 2 0 + # Wait one second. + 1 1 + 2 1 + # Wait one second. + 1 2 + 2 2 + # ... */ #include /* usleep_range */ @@ -34,12 +46,11 @@ static int kthread_func1(void *data) static int kthread_func2(void *data) { - set_current_state(TASK_INTERRUPTIBLE); unsigned int i = 0; while (!kthread_should_stop()) { pr_info("2 %u\n", i); i++; - wait_event(queue, atomic_read(&awake)); + wait_event_interruptible(queue, atomic_read(&awake)); atomic_set(&awake, 0); schedule(); } diff --git a/kernel_module/wait_queue2.c b/kernel_module/wait_queue2.c new file mode 100644 index 0000000..d4d8ed0 --- /dev/null +++ b/kernel_module/wait_queue2.c @@ -0,0 +1,79 @@ +/* +Two threads waiting on a single event. +*/ + +#include /* usleep_range */ +#include +#include +#include +#include /* wait_queue_head_t, wait_event_interruptible, wake_up_interruptible */ + +MODULE_LICENSE("GPL"); + +static struct task_struct *kthread_wake; +static struct task_struct *kthread_sleep1; +static struct task_struct *kthread_sleep2; +static wait_queue_head_t queue; +static atomic_t awake1 = ATOMIC_INIT(0); +static atomic_t awake2 = ATOMIC_INIT(0); + +static int kthread_wake_func(void *data) +{ + unsigned int i = 0; + while (!kthread_should_stop()) { + pr_info("0 %u\n", i); + usleep_range(1000000, 1000001); + atomic_set(&awake1, 1); + atomic_set(&awake2, 1); + wake_up(&queue); + i++; + } + i = !i; + wake_up_interruptible(&queue); + return 0; +} + +static int kthread_sleep1_func(void *data) +{ + unsigned int i = 0; + while (!kthread_should_stop()) { + pr_info("1 %u\n", i); + i++; + wait_event(queue, atomic_read(&awake1)); + atomic_set(&awake1, 0); + schedule(); + } + return 0; +} + +static int kthread_sleep2_func(void *data) +{ + unsigned int i = 0; + while (!kthread_should_stop()) { + pr_info("2 %u\n", i); + i++; + wait_event(queue, atomic_read(&awake2)); + atomic_set(&awake2, 0); + schedule(); + } + return 0; +} + +int init_module(void) +{ + init_waitqueue_head(&queue); + kthread_wake = kthread_create(kthread_wake_func, NULL, "wake"); + kthread_sleep1 = kthread_create(kthread_sleep1_func, NULL, "sleep1"); + kthread_sleep2 = kthread_create(kthread_sleep2_func, NULL, "sleep2"); + wake_up_process(kthread_wake); + wake_up_process(kthread_sleep1); + wake_up_process(kthread_sleep2); + return 0; +} + +void cleanup_module(void) +{ + kthread_stop(kthread_wake); + kthread_stop(kthread_sleep1); + kthread_stop(kthread_sleep2); +}