[MULTITASKING] Processes

This commit is contained in:
2016-12-16 19:22:33 +01:00
parent 5e8fbcbb78
commit 5ca2b6994a
8 changed files with 177 additions and 8 deletions

91
kernel/proc/process.c Normal file
View File

@@ -0,0 +1,91 @@
#include <process.h>
#include <thread.h>
#include <debug.h>
#include <scheduler.h>
uint64_t pid = 1;
process_t *init_proc = 0;
process_t *process_spawn(process_t *parent)
{
process_t *proc = kcalloc(1, sizeof(process_t));
proc->pid = pid++;
proc->parent = parent;
proc->P4 = vmm_new_P4();
proc->state = PROC_STATE_READY;
LIST_INIT(proc, children);
LIST_INIT(proc, siblings);
LIST_INIT(proc, threads);
if(parent)
{
LIST_APPEND(parent->children, proc, siblings);
}
if(proc->pid == 1)
init_proc = proc;
return proc;
}
void process_attach(process_t *proc, thread_t *th)
{
LIST_APPEND(proc->threads, th, process_threads);
th->process = proc;
}
void switch_process(process_t *proc)
{
process_t *old = get_current_process();
if(old)
{
if(old == proc)
return;
if(old->state == PROC_STATE_RUNNING)
old->state = PROC_STATE_READY;
}
set_current_process(proc);
if(proc)
{
proc->state = PROC_STATE_RUNNING;
vmm_set_P4(proc->P4);
}
else
{
vmm_set_P4(0);
}
}
void process_exit(process_t *proc, uint64_t status)
{
proc->status = status;
LIST_FOREACH(proc->children, process_t, c, siblings)
{
// Make init process adopt orphaned children
LIST_REMOVE(proc->children, c, siblings);
c->parent = init_proc;
LIST_APPEND(init_proc->children, c, siblings);
}
proc->state = PROC_STATE_ZOMBIE;
}
void process_free(process_t *proc)
{
if(proc->state != PROC_STATE_ZOMBIE)
{
debug_error("Trying to free an unfinished process!\n");
for(;;);
}
LIST_FOREACH(proc->threads, thread_t, th, process_threads)
{
while(th->state == THREAD_STATE_RUNNING || th->state == THREAD_STATE_READY) schedule();
free_thread(th);
}
LIST_REMOVE(proc->parent->children, proc, siblings);
// Free page directory
vmm_free_P4(proc->P4);
// Free process structure
kfree(proc);
}

View File

@@ -41,15 +41,25 @@ void scheduler()
thread_t *old = 0, *new = 0;
if((old = get_last_thread()))
{
if(old->state == THREAD_STATE_RUNNING)
if(old->state != THREAD_STATE_FINISHED && process_alive(old->process))
{
old->state = THREAD_STATE_READY;
scheduler_insert(old);
} else {
old->state = THREAD_STATE_FINISHED;
}
}
while(!(new = scheduler_next()));
if(!process_alive(new->process))
{
new->state = THREAD_STATE_FINISHED;
continue;
}
new->state = THREAD_STATE_RUNNING;
set_last_thread(new);
switch_process(new->process);
switch_thread(scheduler_th, new);
}
}
@@ -60,6 +70,7 @@ void schedule()
thread_t *old = get_current_thread();
switch_process(0);
switch_thread(old, scheduler_th);
}

View File

@@ -1,5 +1,6 @@
#include <thread.h>
#include <stdint.h>
#include <process.h>
#include <mem.h>
#include <list.h>
#include <debug.h>
@@ -23,6 +24,7 @@ thread_t *new_thread(void (*func)(void))
th->stack_pointer = (uint64_t)&stack->RBP;
LIST_INIT(th, ready_queue);
LIST_INIT(th, process_threads);
return th;
}
@@ -42,6 +44,8 @@ void free_thread(thread_t *th)
debug_error("Trying to free a live thread!\n");
for(;;);
}
if(!LIST_EMPTY(th->process_threads))
LIST_REMOVE(th->process->threads, th, process_threads);
thread_stack_t *stack = incptr(th, -offsetof(thread_stack_t, tcb));
kfree(stack);
}