diff options
author | Marvin Borner | 2020-04-26 23:23:42 +0200 |
---|---|---|
committer | Marvin Borner | 2020-04-26 23:23:42 +0200 |
commit | f30c9803f05e90087e367953aa142275f8688f61 (patch) | |
tree | bea9166fad90c42ad4551094a5e6eec9098a7f19 /src/kernel/tasks/process.c | |
parent | 31f671f2137bc09e62de09142bea232c1975c76b (diff) |
Awesome new multitasking system and scheduler
Diffstat (limited to 'src/kernel/tasks/process.c')
-rw-r--r-- | src/kernel/tasks/process.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/kernel/tasks/process.c b/src/kernel/tasks/process.c new file mode 100644 index 0000000..5ac4010 --- /dev/null +++ b/src/kernel/tasks/process.c @@ -0,0 +1,206 @@ +#include <stdint.h> +#include <stddef.h> +#include <kernel/tasks/process.h> +#include <kernel/tasks/userspace.h> +#include <kernel/interrupts/interrupts.h> +#include <kernel/system.h> +#include <kernel/lib/lib.h> +#include <kernel/memory/paging.h> +#include <kernel/memory/alloc.h> +#include <kernel/timer/timer.h> + +uint32_t pid = 0; +struct process *root; +struct process *current_proc = NULL; + +struct regs hold_root; + +extern uint32_t stack_hold; + +void scheduler(struct regs *regs) +{ + memcpy(¤t_proc->registers, regs, sizeof(struct regs)); + + debug("Task switch"); + + timer_handler(regs); + + current_proc = current_proc->next; + if (current_proc == NULL) { + current_proc = root; + } + + while (current_proc->state == PROC_ASLEEP) { + current_proc = current_proc->next; + if (current_proc == NULL) + current_proc = root; + } + + memcpy(regs, ¤t_proc->registers, sizeof(struct regs)); + paging_switch_directory(current_proc->cr3); +} + +void process_init(struct process *proc) +{ + root = proc; + root->pid = pid++; + root->next = NULL; + root->thread = PROC_ROOT; // Unkillable + root->state = PROC_RUNNING; + + current_proc = root; + irq_install_handler(0, scheduler); + userspace_enter(proc); +} + +void process_kill(uint32_t pid) +{ + struct process *proc = process_from_pid(pid); + + if (proc == PID_NOT_FOUND) + panic("Can't kill unknown PID"); + + // flush(proc->stdout); + // flush(proc->stderr); + proc->state = PROC_ASLEEP; + + if (proc->parent != NULL) { + //warn("Child had parent"); + //process_wake(proc->parent->pid); + } +} + +uint32_t process_spawn(struct process *process) +{ + process->next = root->next; + root->next = process; + process->state = PROC_RUNNING; + + process->parent = current_proc; + + //process_suspend(current_proc->pid); + + return process->pid; +} + +int process_wait_gid(uint32_t gid, int *status) +{ + struct process *i = root; + + while (i != NULL) { + if (i->gid == gid) + if (i->state == PROC_ASLEEP) { + *status = i->registers.ebx; + return i->pid; + } + + i = i->next; + } + + return WAIT_OKAY; +} + +int process_wait_pid(uint32_t pid, int *status) +{ + struct process *i = current_proc->next; + + while (i != NULL) { + if (i->pid == pid) { + if (i->state == PROC_ASLEEP) { + *status = i->registers.ebx; + return i->pid; + } else { + return WAIT_OKAY; + } + } + i = i->next; + } + + return WAIT_ERROR; +} + +void process_suspend(uint32_t pid) +{ + struct process *proc = process_from_pid(pid); + + if (proc == PID_NOT_FOUND) { + warn("couldn't find PID for suspension"); + return; + } + + proc->state = PROC_ASLEEP; +} + +void process_wake(uint32_t pid) +{ + struct process *proc = process_from_pid(pid); + + if (proc == PID_NOT_FOUND) + return; + + proc->state = PROC_RUNNING; +} + +uint32_t process_child(struct process *child, uint32_t pid) +{ + process_suspend(pid); + + struct process *parent = process_from_pid(pid); + + if (parent == PID_NOT_FOUND) { + panic("Child process spawned without parent"); + } + + child->parent = parent; + + return process_spawn(child); +} + +uint32_t process_fork(uint32_t pid) +{ + warn("Fork is not implemented"); + + // With struct regs *regs + /*struct page_directory *dir = paging_copy_user_directory(current_proc->cr3); + struct process *proc = process_make_new(); + proc->cr3 = dir; + memcpy(&proc->registers, regs, sizeof(struct regs)); + proc->registers.eax = proc->pid; + proc->pid = current_proc->pid; + + process_spawn(proc);*/ + return pid++; +} + +struct process *process_from_pid(uint32_t pid) +{ + struct process *proc = root; + + while (proc != NULL) { + if (proc->pid == pid) + return proc; + + proc = proc->next; + } + + return PID_NOT_FOUND; +} + +struct process *process_make_new() +{ + struct process *proc = (struct process *)kmalloc_a(sizeof(struct process)); + proc->registers.cs = 0x1B; + proc->registers.ds = 0x23; + proc->registers.ss = 0x23; + proc->cr3 = paging_make_directory(); + + proc->brk = 0x50000000; + + int i; + for (i = 0; i < 1024; i++) + proc->cr3->tables[i] = paging_root_directory->tables[i]; + + proc->pid = pid++; + + return proc; +}
\ No newline at end of file |