ish/kernel/process.c
2017-12-19 22:48:43 -08:00

88 lines
2.1 KiB
C

#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include "kernel/calls.h"
#include "kernel/process.h"
#include "emu/memory.h"
__thread struct process *current;
static struct pid pids[MAX_PID + 1] = {};
lock_t pids_lock = LOCK_INITIALIZER;
static bool pid_empty(struct pid *pid) {
return pid->proc == NULL && list_empty(&pid->session) && list_empty(&pid->group);
}
struct pid *pid_get(dword_t id) {
struct pid *pid = &pids[id];
if (pid_empty(pid))
return NULL;
return pid;
}
struct process *pid_get_proc(dword_t id) {
struct pid *pid = pid_get(id);
if (pid == NULL) return NULL;
struct process *proc = pid->proc;
return proc;
}
struct process *process_create() {
lock(pids_lock);
static int cur_pid = 1;
while (!pid_empty(&pids[cur_pid])) {
cur_pid++;
if (cur_pid > MAX_PID) cur_pid = 0;
}
struct pid *pid = &pids[cur_pid];
pid->id = cur_pid;
list_init(&pid->session);
list_init(&pid->group);
struct process *proc = malloc(sizeof(struct process));
if (proc == NULL)
return NULL;
*proc = (struct process) {};
proc->pid = pid->id;
pid->proc = proc;
unlock(pids_lock);
list_init(&proc->children);
list_init(&proc->siblings);
lock_init(proc->lock);
pthread_cond_init(&proc->child_exit, NULL);
pthread_cond_init(&proc->vfork_done, NULL);
proc->has_timer = false;
return proc;
}
void process_destroy(struct process *proc) {
list_remove(&proc->siblings);
lock(pids_lock);
struct pid *pid = pid_get(proc->pid);
list_remove(&proc->group);
list_remove(&proc->session);
pid->proc = NULL;
unlock(pids_lock);
mem_release(proc->cpu.mem);
free(proc);
}
void (*process_run_hook)() = NULL;
static void *process_run(void *proc) {
current = proc;
if (process_run_hook)
process_run_hook();
else
cpu_run(&current->cpu);
assert(false);
}
void start_thread(struct process *proc) {
if (pthread_create(&proc->thread, NULL, process_run, proc) < 0)
abort();
pthread_detach(proc->thread);
}