From 1ab3a2bd22aac0d097f8587ae895147205aa3b5f Mon Sep 17 00:00:00 2001 From: antifallobst Date: Fri, 3 Mar 2023 23:51:24 +0100 Subject: [PATCH] feature (proc): implemented basic child processes --- kernel/inc/proc/process.h | 22 ++++++++++------ kernel/inc/proc/scheduler.h | 1 + kernel/src/kmain.c | 18 +++++++------ kernel/src/proc/process.c | 15 ++++++----- kernel/src/proc/scheduler.c | 51 +++++++++++++++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 22 deletions(-) diff --git a/kernel/inc/proc/process.h b/kernel/inc/proc/process.h index cdf3b10..79c6ac5 100644 --- a/kernel/inc/proc/process.h +++ b/kernel/inc/proc/process.h @@ -36,16 +36,22 @@ typedef enum { typedef struct process_T process_T; struct process_T{ - char name[128]; - pid_t id; - void* chunk; - uint32_t chunk_id; + char name [128]; + pid_t id; + void* chunk; + uint32_t chunk_id; - process_T* parent; - void* threads; + uint32_t num_threads; + void* threads; + + process_T* parent; + process_T* childs; + process_T* prev; + process_T* next; }; -pid_t process_spawn (pid_t parent, string_t name); -void process_kill (pid_t process); +pid_t process_spawn (pid_t parent, string_t name); +void process_kill_pid (pid_t pid); +void process_kill (process_T* process); #endif //NOX_PROCESS_H diff --git a/kernel/inc/proc/scheduler.h b/kernel/inc/proc/scheduler.h index 928f812..372ef87 100644 --- a/kernel/inc/proc/scheduler.h +++ b/kernel/inc/proc/scheduler.h @@ -54,6 +54,7 @@ typedef struct { void scheduler_init (); cpu_state_T* scheduler_start (cpu_state_T* state); bool scheduler_is_initialized (); +void scheduler_dump_info (process_T* process, uint8_t indent); thread_T* scheduler_register_thread (thread_T* thread); void scheduler_pause_thread (thread_T* thread); diff --git a/kernel/src/kmain.c b/kernel/src/kmain.c index bf3ba15..d65a4c3 100644 --- a/kernel/src/kmain.c +++ b/kernel/src/kmain.c @@ -110,16 +110,18 @@ void kmain(boot_info_T boot_info) { elf_init_kernel_exec(&boot_info); - pid_t proc1 = process_spawn(PROCESS_NONE, "test process 1"); - thread_T* proc1_thread1 = thread_spawn(proc1, test1); - thread_T* proc1_thread2 = thread_spawn(proc1, test2); - thread_T* proc1_thread3 = thread_spawn(proc1, test3); + pid_t proc1 = process_spawn(PROCESS_KERNEL, "test_1"); - thread_start(proc1_thread1); - thread_start(proc1_thread2); - thread_start(proc1_thread3); + pid_t proc1_1 = process_spawn(proc1, "test_1-1"); + thread_spawn(proc1_1, NULL); + pid_t proc1_2 = process_spawn(proc1, "test_1-2"); - process_kill(proc1); + pid_t proc2 = process_spawn(PROCESS_KERNEL, "test_2"); + + scheduler_dump_info(scheduler_get_process(PROCESS_KERNEL), 0); + + process_kill_pid(proc1); + scheduler_dump_info(scheduler_get_process(PROCESS_KERNEL), 0); // vfs_node_T* node = vfs_resolve_path(&g_root_fs, "/initrd/test.elf"); // diff --git a/kernel/src/proc/process.c b/kernel/src/proc/process.c index bdf0865..bd480dc 100644 --- a/kernel/src/proc/process.c +++ b/kernel/src/proc/process.c @@ -28,8 +28,9 @@ pid_t process_spawn(pid_t parent, string_t name) { process_T* process = memory_allocate(sizeof(process_T)); - process->threads = NULL; - process->parent = scheduler_get_process(parent); + process->num_threads = 0; + process->threads = NULL; + process->parent = scheduler_get_process(parent); memory_copy(name, process->name, MIN(string_length(name), 127)); @@ -38,10 +39,12 @@ pid_t process_spawn(pid_t parent, string_t name) { return scheduler_register_process(process); } -void process_kill(pid_t process) { - process_T* proc = scheduler_get_process(process); +void process_kill_pid(pid_t pid) { + process_kill(scheduler_get_process(pid)); +} - scheduler_kill_process(proc); +void process_kill(process_T* process) { + scheduler_kill_process(process); - memory_free(proc); + memory_free(process); } \ No newline at end of file diff --git a/kernel/src/proc/scheduler.c b/kernel/src/proc/scheduler.c index 0210214..82f1889 100644 --- a/kernel/src/proc/scheduler.c +++ b/kernel/src/proc/scheduler.c @@ -39,6 +39,21 @@ void scheduler_update_info() { graphics_buffer_draw_string(g_scheduler_info_buffer, 0, 0, g_color_palette[COLOR_PAL_GREEN], buffer); } +void scheduler_dump_info(process_T* process, uint8_t indent) { + char buf[indent+1]; + memory_set(buf, ' ', indent); + buf[indent] = '\0'; + + log(LOG_NONE, "%s<%d> %s [%d]", buf, process->id, process->name, process->num_threads); + + process_T* child = process->childs; + while (child != NULL) { + scheduler_dump_info(child, indent+2); + + child = child->next; + } +} + scheduler_processes_chunk_T* scheduler_processes_chunk_create(scheduler_processes_chunk_T* prev) { scheduler_processes_chunk_T* chunk = memory_allocate(sizeof(scheduler_processes_chunk_T)); @@ -114,6 +129,7 @@ thread_T* scheduler_register_thread(thread_T* thread) { thread->process->threads = thread; + thread->process->num_threads++; g_scheduler.num_threads++; log(LOG_INFO, " Registered thread"); @@ -149,6 +165,7 @@ void scheduler_kill_thread(thread_T* thread) { thread->local_prev->local_next = thread->local_next; } + thread->process->num_threads--; g_scheduler.num_threads--; log(LOG_INFO, " Killed thread"); @@ -178,6 +195,20 @@ pid_t scheduler_register_process(process_T* process) { process->chunk = chunk; process->chunk_id = i; process->id = pid + i; + process->childs = NULL; + process->prev = NULL; + + if (process->parent != NULL) { + process->next = process->parent->childs; + + if (process->next != NULL) { + process->next->prev = process; + } + + process->parent->childs = process; + } else { + process->next = NULL; + } chunk->num_free_pids--; g_scheduler.num_processes++; @@ -199,6 +230,12 @@ void scheduler_kill_process(process_T* process) { bitmap_set(&chunk->processes_bitmap, process->chunk_id, false); chunk->processes[process->chunk_id] = NULL; + process_T* child = process->childs; + while (child != NULL) { + process_T* next = child->next; + process_kill(child); + child = next; + } thread_T* thread = process->threads; while (thread != NULL) { @@ -207,6 +244,20 @@ void scheduler_kill_process(process_T* process) { thread = next; } + if (process->parent != NULL) { + if (process->parent->childs == process) { + process->parent->childs = process->next; + } + + if (process->next != NULL) { + process->next->prev = process->prev; + } + + if (process->prev != NULL) { + process->prev->next = process->next; + } + } + chunk->num_free_pids++; g_scheduler.num_processes--;