#include "process.h" #include "alloc.h" #include "irq.h" #include "klibc.h" #include "list.h" #include "mmuContext.h" #include "types.h" #include "thread.h" #include "uaddrspace.h" struct process { char name[PROCESS_NAME_MAX_LENGTH]; int ref; pid_t pid; pid_t nextTid; struct uAddrSpace *addrSpace; 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->addrSpace = uAddrSpaceCreate(new); if(new->addrSpace == NULL){ free(new); return NULL; } strzcpy(new->name, name, PROCESS_NAME_MAX_LENGTH); new->ref = 1; disable_IRQs(flags); new->pid = nextPid++; new->nextTid = new->pid; 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("%lu %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%lx Current\n", (vaddr_t)th); } else { printf(" th: 0x%lx in 0x%lx\n", (vaddr_t)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; int ret; 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); ret = uAddrSpaceDelete(proc->addrSpace); free(proc); return ret; } 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; } char *processGetName(struct process *proc){ return proc->name; } struct mmu_context *processGetMMUContext(struct process *proc) { return uAddrSpaceGetMMUContext(proc->addrSpace); } struct uAddrSpace *processGetAddrSpace(struct process *proc){ return proc->addrSpace; } int processInitHeap(struct process *proc, uaddr_t lastUserAddr){ return uAddrSpaceSetHeap(proc->addrSpace, lastUserAddr, 0); } pid_t processGetId(struct process *proc){ return proc->pid; } pid_t processGetNextTid(struct process *proc){ return proc->nextTid++; } //Should be called with IRQ disabled struct thread *processGetThread(struct process *proc, pid_t tid) { int count; struct thread *th; struct thread *thFound = NULL; list_foreach_named(proc->thList, th, count, prevInProcess, nextInProcess) { if (th->tid == tid) { thFound = th; break; } } return thFound; } int processJoinThread(struct process *proc, pid_t tid) { uint32_t flags; struct thread *th; int ret = -1; disable_IRQs(flags); th = processGetThread(proc, tid); if (th && th->wqExit) { wait(th->wqExit); ret = 0; } restore_IRQs(flags); return ret; }