diff --git a/headers/task.h b/headers/task.h index 5033ce8..aae4016 100644 --- a/headers/task.h +++ b/headers/task.h @@ -8,7 +8,7 @@ extern struct task *current_task; -enum status { ZOMBIE, THREAD, RUN, WAIT, SLEEP, STOPPED }; +enum status { ZOMBIE, THREAD, RUN, WAIT, SLEEP, STOPPED, FORKED }; enum owner { OWNER_KERNEL, OWNER_USER }; #define STACK_SIZE PAGE_SIZE * 4 @@ -31,9 +31,13 @@ struct task { void scheduler(void); void switch_to_task(struct task *next_task); -void exec_fn(void (*fn)(void)); struct task *create_task(u8 uid); i8 create_kernel_task(void); void remove_task(struct task *task); +struct task *copy_task(const struct task *task); +void kfork(struct task *daddy); + +// utils +void exec_fn(void (*fn)(void)); u16 fork(void); u16 wait(void); diff --git a/src/kernel.c b/src/kernel.c index ee1a571..eae316a 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -43,10 +43,13 @@ static void owo(void) static void awa(void) { - if (fork() < 0) + u32 pid = fork(); + PRINT_INT(pid); + if (pid < 0) kprintf("camille il a une grosse bite (18cm)\n"); kprintf("awaille\n"); - wait(); + if (pid) + wait(); } void kernel_main(multiboot_info_t *mbd, u32 magic) diff --git a/src/multitasking/fork.c b/src/multitasking/fork.c index 85a6fa2..0a9eb73 100644 --- a/src/multitasking/fork.c +++ b/src/multitasking/fork.c @@ -1,22 +1,27 @@ #include "interrupts.h" -#include "string.h" +#include "kprintf.h" #include "task.h" #include "types.h" u16 fork(void) { - if (current_task->esp == current_task->esp0 + STACK_SIZE) - scheduler(); - cli(); - struct task *child = create_task(current_task->uid); - if (!child) - return -1; - child->daddy = current_task; - current_task->child = child; - memcpy(child->esp0, current_task->esp0, STACK_SIZE); - u8 *daddy_esp; - asm("movl %%esp, %0" : "=m"(daddy_esp)); - child->esp = child->esp0 + (daddy_esp - current_task->esp0); - toris(); - return current_task == child ? 0 : child->pid; + current_task->status = FORKED; + scheduler(); + return current_task->child ? current_task->child->pid : 0; } + +void kfork(struct task *daddy) +{ + cli(); + struct task *child = copy_task(daddy); + if (!child) { + kprintf(KERN_ALERT "Fork failed ! retry at the next loop"); + toris(); + return; + } + child->daddy = daddy; + daddy->child = child; + daddy->status = RUN; + child->status = RUN; + toris(); +} \ No newline at end of file diff --git a/src/multitasking/scheduler.c b/src/multitasking/scheduler.c index f6977e1..3368050 100644 --- a/src/multitasking/scheduler.c +++ b/src/multitasking/scheduler.c @@ -11,14 +11,18 @@ struct task *current_task; void scheduler(void) { + // ZOMBIE, THREAD, RUN, WAIT, SLEEP, STOPPED, FORKED + void (*func[])(struct task *) = {remove_task, NULL, NULL, NULL, + NULL, remove_task, kfork}; + if (!current_task) // || current_task->next == current_task) return; cli(); struct task *it = current_task->next; while (it && it->status != RUN) { - if (it->status == STOPPED || it->status == ZOMBIE) { + if (it != current_task && func[it->status]) { struct task *new_it = it->prev; - remove_task(it); + func[it->status](it); it = new_it; } it = it->next; diff --git a/src/multitasking/task.c b/src/multitasking/task.c index 2364705..12aee49 100644 --- a/src/multitasking/task.c +++ b/src/multitasking/task.c @@ -5,6 +5,7 @@ #include "kpanic.h" #include "kprintf.h" #include "memory.h" +#include "string.h" #include #include @@ -81,6 +82,17 @@ void remove_task(struct task *task) } } +struct task *copy_task(const struct task *task) +{ + struct task *new_task = create_task(task->uid); + if (!new_task) + return NULL; + memcpy(new_task->esp0, task->esp0, STACK_SIZE); + new_task->esp = new_task->esp0 + (task->esp - task->esp0); + new_task->status = task->status; + return new_task; +} + void exit_task(void) { cli();