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..bcedd54 --- /dev/null +++ b/10-ConcurrencyAndSynchronization/thread_test.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +#define THREAD_NUMBER 5 +static int delay_sec = 5; +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 (!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); + return 0; +} + +int test_thread(void) +{ + int i = 0; + + pr_info("thread: main process [%d] is running\n", current->pid); + 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; +} + +module_init(test_thread); + +MODULE_AUTHOR("Oleksandr.Siruk "); +MODULE_DESCRIPTION("Simple Kernel module example"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1");