1// SPDX-License-Identifier: GPL-3.0-or-later
2// Special processes: (pid 0: idle, pid 1: init, pid 2: kthreadd)
3
4#include "mos/filesystem/sysfs/sysfs.h"
5#include "mos/filesystem/sysfs/sysfs_autoinit.h"
6#include "mos/mm/slab_autoinit.h"
7#include "mos/syslog/printk.h"
8#include "mos/tasks/schedule.h"
9
10#include <mos/lib/structures/hashmap.h>
11#include <mos/lib/structures/hashmap_common.h>
12#include <mos/misc/panic.h>
13#include <mos/platform/platform.h>
14#include <mos/tasks/process.h>
15#include <mos/tasks/task_types.h>
16#include <mos/tasks/thread.h>
17#include <mos_stdlib.h>
18
19#define PROCESS_HASHTABLE_SIZE 512
20#define THREAD_HASHTABLE_SIZE 512
21
22slab_t *process_cache = NULL, *thread_cache = NULL;
23SLAB_AUTOINIT("process", process_cache, process_t);
24SLAB_AUTOINIT("thread", thread_cache, thread_t);
25
26static void dump_process(void)
27{
28 if (current_thread)
29 {
30 process_t *proc = current_process;
31 pr_info("process %pp ", (void *) proc);
32 if (proc->parent)
33 pr_info2("parent %pp ", (void *) proc->parent);
34 else
35 pr_info2("parent <none> ");
36 process_dump_mmaps(process: proc);
37 }
38 else
39 {
40 pr_warn("no current thread");
41 }
42}
43
44MOS_PANIC_HOOK(dump_process, "Dump current process");
45
46void tasks_init()
47{
48 hashmap_init(map: &process_table, PROCESS_HASHTABLE_SIZE, hash_func: hashmap_identity_hash, compare_func: hashmap_simple_key_compare);
49 hashmap_init(map: &thread_table, THREAD_HASHTABLE_SIZE, hash_func: hashmap_identity_hash, compare_func: hashmap_simple_key_compare);
50}
51
52// ! sysfs support
53
54bool _process_do_print(uintn key, void *val, void *data)
55{
56 MOS_UNUSED(key);
57 sysfs_file_t *f = data;
58 process_t *proc = val;
59 sysfs_printf(file: f, fmt: "%pp, parent=%pp, main_thread=%pt, exit_status=%d\n", (void *) proc, (void *) proc->parent, (void *) proc->main_thread, proc->exit_status);
60 return true;
61}
62
63bool _thread_do_print(uintn key, void *val, void *data)
64{
65 MOS_UNUSED(key);
66 sysfs_file_t *f = data;
67 thread_t *thread = val;
68 sysfs_printf(file: f, fmt: "%pt, state=%c, mode=%s, owner=%pp, stack=%p (%zu bytes)\n", (void *) thread, thread_state_str(state: thread->state),
69 thread->mode == THREAD_MODE_KERNEL ? "kernel" : "user", (void *) thread->owner, (void *) thread->u_stack.top, thread->u_stack.capacity);
70 return true;
71}
72
73static bool tasks_sysfs_process_list(sysfs_file_t *f)
74{
75 hashmap_foreach(map: &process_table, func: _process_do_print, data: (void *) f);
76 return true;
77}
78
79static bool tasks_sysfs_thread_list(sysfs_file_t *f)
80{
81 hashmap_foreach(map: &thread_table, func: _thread_do_print, data: (void *) f);
82 return true;
83}
84
85static sysfs_item_t task_sysfs_items[] = {
86 SYSFS_RO_ITEM("processes", tasks_sysfs_process_list),
87 SYSFS_RO_ITEM("threads", tasks_sysfs_thread_list),
88};
89
90SYSFS_AUTOREGISTER(tasks, task_sysfs_items);
91