diff options
author | Anton Kling <anton@kling.gg> | 2024-03-26 11:40:39 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-03-26 11:40:39 +0100 |
commit | 297231bb3602d868d3891d357026c53f9fcc2402 (patch) | |
tree | 6c4f21db84912750f6f464b26bf1e4503d1fe479 /kernel/sched/scheduler.c | |
parent | 3deb2df8e62a5f0a5535ee734a5aa13b0959f53f (diff) |
Increase support for signals
Diffstat (limited to 'kernel/sched/scheduler.c')
-rw-r--r-- | kernel/sched/scheduler.c | 72 |
1 files changed, 50 insertions, 22 deletions
diff --git a/kernel/sched/scheduler.c b/kernel/sched/scheduler.c index ebf2c32..7afd203 100644 --- a/kernel/sched/scheduler.c +++ b/kernel/sched/scheduler.c @@ -8,6 +8,7 @@ #include <fs/vfs.h> #include <interrupts.h> #include <queue.h> +#include <signal.h> // FIXME: Use the process_t struct instead or keep this contained in it. TCB *current_task_TCB; @@ -188,8 +189,7 @@ void tasking_init(void) { } int i = 0; -void free_process(void) { - process_t *p = current_task; +void free_process(process_t *p) { kprintf("pid: %x\n", p->pid); kprintf("Exiting process: %s\n", p->program_name); // free_process() will purge all contents such as allocated frames @@ -199,53 +199,57 @@ void free_process(void) { // Do a special free for shared memory which avoids labeling // underlying frames as "unused". for (int i = 0; i < 100; i++) { - vfs_close(i); - if (!current_task->maps[i]) { + vfs_close_process(p, i); + if (!p->maps[i]) { continue; } - MemoryMap *m = current_task->maps[i]; + MemoryMap *m = p->maps[i]; mmu_remove_virtual_physical_address_mapping(m->u_address, m->length); } // NOTE: Kernel stuff begins at 0x90000000 - mmu_free_address_range((void *)0x1000, 0x90000000); + mmu_free_address_range((void *)0x1000, 0x90000000, p->cr3); list_free(&p->read_list); list_free(&p->write_list); list_free(&p->disconnect_list); } -void exit(int status) { - assert(current_task->pid != 1); - if (current_task->parent) { - current_task->parent->halts[WAIT_CHILD_HALT] = 0; - current_task->parent->child_rc = status; +void exit_process(process_t *p, int status) { + assert(p->pid != 1); + if (p->parent) { + p->parent->halts[WAIT_CHILD_HALT] = 0; + p->parent->child_rc = status; } - process_t *new_task = current_task; - for (; new_task == current_task;) { + process_t *new_task = p; + for (; new_task == p;) { if (!new_task->next) { new_task = ready_queue; } new_task = new_task->next; } - free_process(); + free_process(p); + p->dead = 1; // Remove current_task from list for (process_t *tmp = ready_queue; tmp;) { - if (tmp == current_task) // current_task is ready_queue(TODO: - // Figure out whether this could even - // happen) + if (tmp == p) // current_task is ready_queue(TODO: + // Figure out whether this could even + // happen) { - ready_queue = current_task->next; + ready_queue = p->next; break; } - if (tmp->next == current_task) { + if (tmp->next == p) { tmp->next = tmp->next->next; break; } tmp = tmp->next; } - current_task->dead = 1; +} + +void exit(int status) { + exit_process(current_task, status); switch_task(); } @@ -434,13 +438,20 @@ process_t *next_task(process_t *s) { if (!c) { c = ready_queue; } + if (c->is_interrupted) { + break; + } if (s == c) { - wait_for_interrupt(); + // wait_for_interrupt(); } if (c->sleep_until > pit_num_ms()) { continue; } - if (is_halted(c) || c->dead) { + if (c->dead) { + kprintf("dead process\n"); + continue; + } + if (is_halted(c)) { continue; } break; @@ -448,6 +459,22 @@ process_t *next_task(process_t *s) { return c; } +void signal_process(process_t *p, int sig) { + assert(sig < 32); + kprintf("sending signal to: %x\n", p); + if (!p->signal_handlers[sig]) { + if (SIGTERM == sig) { + kprintf("HAS NO SIGTERM\n"); + exit_process(p, 1 /*TODO: what should the status be?*/); + } else { + // TODO: Should also exit proess(I think) + assert(0); + } + } + signal_t signal = {.handler_ip = (uintptr_t)p->signal_handlers[sig]}; + process_push_signal(p, signal); +} + int kill(pid_t pid, int sig) { process_t *p = current_task; p = p->next; @@ -466,6 +493,7 @@ int kill(pid_t pid, int sig) { if (p->pid != pid) { return -ESRCH; } + signal_process(p, sig); return 0; } |