From 36f48aa9c70739830bbc532ad6cd6e75b6196c30 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Thu, 25 May 2017 08:18:03 +0100 Subject: [PATCH] More simple kthread experiments, failed wait queue experiment --- README.md | 2 + kernel_module/kthread_uninterruptible.c | 38 +++++++++++++++ kernel_module/kthreads.c | 53 ++++++++++++++++++++ kernel_module/poll.c | 5 +- kernel_module/wait_queue.c | 65 +++++++++++++++++++++++++ 5 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 kernel_module/kthread_uninterruptible.c create mode 100644 kernel_module/kthreads.c create mode 100644 kernel_module/wait_queue.c diff --git a/README.md b/README.md index 9954eff..a7da065 100644 --- a/README.md +++ b/README.md @@ -231,5 +231,7 @@ ARM TODOs: 1. [workqueue](kernel_module/workqueue.c) 1. [sleep](kernel_module/sleep.c) 1. [kthread](kernel_module/kthread.c) + 1. [kthreads](kernel_module/kthreads.c) + 1. [kthread_uninterruptible](kernel_module/kthread_uninterruptible.c) 1. [timer](kernel_module/timer.c) 1. [work_from_work](kernel_module/work_from_work.c) diff --git a/kernel_module/kthread_uninterruptible.c b/kernel_module/kthread_uninterruptible.c new file mode 100644 index 0000000..0716cc8 --- /dev/null +++ b/kernel_module/kthread_uninterruptible.c @@ -0,0 +1,38 @@ +/* +Let's block the entire kernel! Yay! + +Also try after dmesg -n 1 to become convinced of the full blockage. +*/ + +#include +#include +#include + +MODULE_LICENSE("GPL"); + +static struct task_struct *kthread; + +static int work_func(void *data) +{ + set_current_state(TASK_UNINTERRUPTIBLE); + int i = 0; + while (!kthread_should_stop()) { + printk(KERN_INFO "%d\n", i); + i++; + if (i == 10) + i = 0; + } + return 0; +} + +int init_module(void) +{ + kthread = kthread_create(work_func, NULL, "mykthread"); + wake_up_process(kthread); + return 0; +} + +void cleanup_module(void) +{ + kthread_stop(kthread); +} diff --git a/kernel_module/kthreads.c b/kernel_module/kthreads.c new file mode 100644 index 0000000..0ede48a --- /dev/null +++ b/kernel_module/kthreads.c @@ -0,0 +1,53 @@ +/* +2 kthreads!!! Will they interleave??? Yup. +*/ + +#include /* usleep_range */ +#include +#include +#include + +MODULE_LICENSE("GPL"); + +static struct task_struct *kthread1, *kthread2; + +static int work_func1(void *data) +{ + int i = 0; + while (!kthread_should_stop()) { + printk(KERN_INFO "1 %d\n", i); + usleep_range(1000000, 1000001); + i++; + if (i == 10) + i = 0; + } + return 0; +} + +static int work_func2(void *data) +{ + int i = 0; + while (!kthread_should_stop()) { + printk(KERN_INFO "2 %d\n", i); + usleep_range(1000000, 1000001); + i++; + if (i == 10) + i = 0; + } + return 0; +} + +int init_module(void) +{ + kthread1 = kthread_create(work_func1, NULL, "mykthread1"); + kthread2 = kthread_create(work_func2, NULL, "mykthread2"); + wake_up_process(kthread1); + wake_up_process(kthread2); + return 0; +} + +void cleanup_module(void) +{ + kthread_stop(kthread1); + kthread_stop(kthread2); +} diff --git a/kernel_module/poll.c b/kernel_module/poll.c index 181c64b..834fd2e 100644 --- a/kernel_module/poll.c +++ b/kernel_module/poll.c @@ -1,9 +1,9 @@ /* +TODO now yet waiting for anything! + Basic poll file_operation example. Waits for a second, give jiffies to user, wait for a second... - -usleep_range */ #include /* copy_from_user, copy_to_user */ @@ -17,6 +17,7 @@ usleep_range #include #include #include /* printk */ +#include /* wait_queue_head_t, wait_event_interruptible, wake_up_interruptible */ MODULE_LICENSE("GPL"); diff --git a/kernel_module/wait_queue.c b/kernel_module/wait_queue.c new file mode 100644 index 0000000..9e1f992 --- /dev/null +++ b/kernel_module/wait_queue.c @@ -0,0 +1,65 @@ +/* +TODO get working. Thread 2 only wakes up once! Wake thread 2 up every 2 seconds from thread 1. +*/ + +#include /* usleep_range */ +#include +#include +#include +#include /* wait_queue_head_t, wait_event_interruptible, wake_up_interruptible */ + +MODULE_LICENSE("GPL"); + +static struct task_struct *kthread1, *kthread2; +static wait_queue_head_t queue; +static int awake = 0; + +static int kthread_func1(void *data) +{ + int i = 0; + while (!kthread_should_stop()) { + awake = !awake; + pr_info("1 %d\n", i); + wake_up_interruptible(&queue); + schedule(); + usleep_range(1000000, 1000001); + i++; + if (i == 10) + i = 0; + } + i = !i; + wake_up_interruptible(&queue); + return 0; +} + +static int kthread_func2(void *data) +{ + set_current_state(TASK_INTERRUPTIBLE); + int i = 0; + while (!kthread_should_stop()) { + wait_event(queue, awake); + pr_info("2 %d\n", i); + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + i++; + if (i == 10) + i = 0; + } + return 0; +} + +int init_module(void) +{ + init_waitqueue_head(&queue); + kthread1 = kthread_create(kthread_func1, NULL, "mykthread1"); + kthread2 = kthread_create(kthread_func2, NULL, "mykthread2"); + wake_up_process(kthread1); + wake_up_process(kthread2); + return 0; +} + +void cleanup_module(void) +{ + kthread_stop(kthread1); + kthread_stop(kthread2); +}