#include "process.h" #include "alloc.h" #include "irq.h" #include "klibc.h" #include "list.h" #include "mmuContext.h" struct process { char name[PROCESS_NAME_MAX_LENGTH]; int ref; int pid; struct mmu_context *context; struct thread *thList; struct process *prev, *next; }; static struct process *processList; static int nextPid; int processSetup() { list_init(processList); allocBookSlab(sizeof(struct process), PAGE_SIZE * 3, 0, 0); nextPid = 0; return 0; } struct process *processCreate(char *name) { uint32_t flags; struct process *new = (struct process *)malloc(sizeof(struct process)); if (new == NULL) return NULL; new->context = mmuContextCreate(); if (new->context == NULL) { free(new); return NULL; } strzcpy(new->name, name, PROCESS_NAME_MAX_LENGTH); new->ref = 1; disable_IRQs(flags); new->pid = nextPid++; list_add_tail(processList, new); restore_IRQs(flags); return new; } void processListPrint() { struct process *proc; int nbProcs; struct thread *cur = getCurrentThread(); printf("PID NAME NBTHREAD REF\n"); list_foreach(processList, proc, nbProcs) { struct thread *th; int nbTh; printf("%d %s %d %d\n", proc->pid, proc->name, processCountThread(proc), proc->ref); list_foreach_named(proc->thList, th, nbTh, prevInProcess, nextInProcess) { if (th == cur) { printf(" th: 0x%x Current\n", th); } else { printf(" th: 0x%x in 0x%x\n", th, cpu_context_get_PC(th->cpuState)); } } } } int processCountThread(struct process *proc) { int count; struct thread *th; list_foreach_named(proc->thList, th, count, prevInProcess, nextInProcess) {} return count; } int processRef(struct process *proc) { uint32_t flags; // ref == 0 -> delete assert(proc->ref > 0); disable_IRQs(flags); proc->ref++; restore_IRQs(flags); return 0; } int processUnref(struct process *proc) { uint32_t flags; assert(proc->ref > 0); disable_IRQs(flags); proc->ref--; if (proc->ref > 0) { restore_IRQs(flags); return -EBUSY; } list_delete(processList, proc); restore_IRQs(flags); mmuContextUnref(proc->context); free(proc); return 0; } int processAddThread(struct process *proc, struct thread *th) { uint32_t flags; assert(proc->ref > 0); th->process = proc; disable_IRQs(flags); processRef(proc); list_add_tail_named(proc->thList, th, prevInProcess, nextInProcess); restore_IRQs(flags); return 0; } int processRemoveThread(struct thread *th) { uint32_t flags; struct process *proc; disable_IRQs(flags); proc = th->process; list_delete_named(proc->thList, th, prevInProcess, nextInProcess); restore_IRQs(flags); processUnref(proc); return 0; } int processSetName(struct process *proc, char *name) { assert(name != NULL); strzcpy(proc->name, name, PROCESS_NAME_MAX_LENGTH); return 0; } struct mmu_context *processGetMMUContext(struct process *proc) { return proc->context; }