1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | |
3 | #include "mos/tasks/schedule.h" |
4 | |
5 | #include <mos/lib/structures/hashmap.h> |
6 | #include <mos/syslog/printk.h> |
7 | #include <mos/tasks/kthread.h> |
8 | #include <mos/tasks/process.h> |
9 | #include <mos/tasks/task_types.h> |
10 | #include <mos/tasks/thread.h> |
11 | #include <mos_stdlib.h> |
12 | |
13 | static process_t *kthreadd = NULL; |
14 | |
15 | typedef struct kthread_arg |
16 | { |
17 | thread_entry_t entry; |
18 | void *arg; |
19 | } kthread_arg_t; |
20 | |
21 | static void kthread_entry(void *arg) |
22 | { |
23 | kthread_arg_t *kthread_arg = arg; |
24 | kthread_arg->entry(kthread_arg->arg); |
25 | kfree(ptr: kthread_arg); |
26 | thread_exit(current_thread); |
27 | } |
28 | |
29 | void kthread_init(void) |
30 | { |
31 | kthreadd = process_allocate(NULL, name: "kthreadd" ); |
32 | MOS_ASSERT_X(kthreadd->pid == 2, "kthreadd should have pid 2" ); |
33 | hashmap_put(map: &process_table, key: kthreadd->pid, value: kthreadd); |
34 | } |
35 | |
36 | thread_t *kthread_create(thread_entry_t entry, void *arg, const char *name) |
37 | { |
38 | thread_t *thread = kthread_create_no_sched(entry, arg, name); |
39 | scheduler_add_thread(thread); |
40 | return thread; |
41 | } |
42 | |
43 | thread_t *kthread_create_no_sched(thread_entry_t entry, void *arg, const char *name) |
44 | { |
45 | MOS_ASSERT_X(kthreadd, "kthreadd not initialized" ); |
46 | pr_dinfo2(thread, "creating kernel thread '%s'" , name); |
47 | kthread_arg_t *kthread_arg = kmalloc(sizeof(kthread_arg_t)); |
48 | kthread_arg->entry = entry; |
49 | kthread_arg->arg = arg; |
50 | thread_t *thread = thread_new(owner: kthreadd, mode: THREAD_MODE_KERNEL, name, stack_size: 0, NULL); |
51 | platform_context_setup_child_thread(thread, entry: kthread_entry, arg: kthread_arg); |
52 | thread_complete_init(thread); |
53 | return thread; |
54 | } |
55 | |