From cd95b04ea65febfb0bd08db4388cc0231ba673dc Mon Sep 17 00:00:00 2001 From: Oleksandr Siruk Date: Thu, 20 Dec 2018 17:19:34 +0200 Subject: [PATCH 1/2] Lesson_10: Add kernel module which start separate thread with kthread_run --- 10-ConcurrencyAndSynchronization/Makefile | 15 +++++++ .../thread_test.c | 42 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 10-ConcurrencyAndSynchronization/Makefile create mode 100644 10-ConcurrencyAndSynchronization/thread_test.c diff --git a/10-ConcurrencyAndSynchronization/Makefile b/10-ConcurrencyAndSynchronization/Makefile new file mode 100644 index 0000000..22cc52e --- /dev/null +++ b/10-ConcurrencyAndSynchronization/Makefile @@ -0,0 +1,15 @@ +#!/usr/bin/make +obj-m+=thread_test.o +all: kernel_path_check.o + make -C ${BUILD_KERNEL} M=$(PWD) modules +clean: + make -C ${BUILD_KERNEL} M=$(PWD) clean + +kernel_path_check.o: + if [ -z "${BUILD_KERNEL}" ]; \ + then \ + echo 'BUILD_KERNEL is not set. abort'>&2; \ + exit 1; \ + else \ + echo 'BUILD_KERNEL is set. continue'; \ + fi diff --git a/10-ConcurrencyAndSynchronization/thread_test.c b/10-ConcurrencyAndSynchronization/thread_test.c new file mode 100644 index 0000000..e2f2046 --- /dev/null +++ b/10-ConcurrencyAndSynchronization/thread_test.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +static int delay_sec = 5; +static struct task_struct *thread_st; +module_param(delay_sec, int, 0); + +static int thread_func(void *data) +{ + int total_sleep = 0; + + while (1) { + if (total_sleep >= delay_sec) + break; + pr_info("thread: child process [%d] is running for %d seconds\n", + current->pid, total_sleep); + ssleep(1); + total_sleep += 1; + + } + pr_info("thread: child process [%d] is completed. total sleep = %d\n", + current->pid, total_sleep); + return 0; +} + +int test_thread(void) +{ + pr_info("thread: main process [%d] is running\n", current->pid); + thread_st = kthread_run(thread_func, NULL, "test_thread"); + ssleep(delay_sec + 2); + pr_info("thread: main process [%d] is completed\n", current->pid); + return -1; +} + +module_init(test_thread); + +MODULE_AUTHOR("Oleksandr.Siruk "); +MODULE_DESCRIPTION("Simple Kernel module example"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); From 2ccd00203cc250dd3804d6ee4be4d0749b2aeedc Mon Sep 17 00:00:00 2001 From: Oleksandr Siruk Date: Thu, 20 Dec 2018 17:37:21 +0200 Subject: [PATCH 2/2] Lesson_10: Implemented kernel module which start THREAD_NUMBER separate threads This module will start THREAD_NUMBER separate threads which have logging for once per second and will be stoped by parent thread after delay_sec using kthread_should_stop and kthread_stop Signed-off-by: Oleksandr Siruk --- .../thread_test.c | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/10-ConcurrencyAndSynchronization/thread_test.c b/10-ConcurrencyAndSynchronization/thread_test.c index e2f2046..bcedd54 100644 --- a/10-ConcurrencyAndSynchronization/thread_test.c +++ b/10-ConcurrencyAndSynchronization/thread_test.c @@ -3,22 +3,23 @@ #include #include +#define THREAD_NUMBER 5 static int delay_sec = 5; -static struct task_struct *thread_st; +static int thread_num = THREAD_NUMBER; + +static struct task_struct *(thread_st[THREAD_NUMBER]); module_param(delay_sec, int, 0); + static int thread_func(void *data) { int total_sleep = 0; - while (1) { - if (total_sleep >= delay_sec) - break; + while (!kthread_should_stop()) { pr_info("thread: child process [%d] is running for %d seconds\n", current->pid, total_sleep); ssleep(1); total_sleep += 1; - } pr_info("thread: child process [%d] is completed. total sleep = %d\n", current->pid, total_sleep); @@ -27,9 +28,14 @@ static int thread_func(void *data) int test_thread(void) { + int i = 0; + pr_info("thread: main process [%d] is running\n", current->pid); - thread_st = kthread_run(thread_func, NULL, "test_thread"); - ssleep(delay_sec + 2); + for (i = 0; i < thread_num; i++) + thread_st[i] = kthread_run(thread_func, NULL, "test_thread"); + ssleep(delay_sec); + for (i = 0; i < thread_num; i++) + kthread_stop(thread_st[i]); pr_info("thread: main process [%d] is completed\n", current->pid); return -1; }