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
13static process_t *kthreadd = NULL;
14
15typedef struct kthread_arg
16{
17 thread_entry_t entry;
18 void *arg;
19} kthread_arg_t;
20
21static 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
29void 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
36thread_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
43thread_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