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 | |
22 | slab_t *process_cache = NULL, *thread_cache = NULL; |
23 | SLAB_AUTOINIT("process" , process_cache, process_t); |
24 | SLAB_AUTOINIT("thread" , thread_cache, thread_t); |
25 | |
26 | static 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 | |
44 | MOS_PANIC_HOOK(dump_process, "Dump current process" ); |
45 | |
46 | void 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 | |
54 | bool _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 | |
63 | bool _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 | |
73 | static 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 | |
79 | static 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 | |
85 | static 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 | |
90 | SYSFS_AUTOREGISTER(tasks, task_sysfs_items); |
91 | |