diff --git a/core/stdarg.h b/core/stdarg.h index a045ddd..7c40c3c 100644 --- a/core/stdarg.h +++ b/core/stdarg.h @@ -42,10 +42,12 @@ typedef enum { FALSE = 0, TRUE } bool_t; typedef unsigned long size_t; typedef long ssize_t; typedef unsigned long int uintptr_t; +typedef long int intptr_t; #else typedef unsigned int size_t; typedef int ssize_t; typedef unsigned int uintptr_t; +typedef int intptr_t; #endif //__builtin_va_list could be used instead diff --git a/core/uaddrspace.c b/core/uaddrspace.c index 4dd74d2..efd224c 100644 --- a/core/uaddrspace.c +++ b/core/uaddrspace.c @@ -2,6 +2,7 @@ #include "alloc.h" #include "kernel.h" #include "klibc.h" +#include "list.h" #include "mem.h" #include "mmuContext.h" #include "process.h" @@ -50,7 +51,7 @@ struct mappedRessource { struct uAddrSpace *uAddrSpaceCreate(struct process *proc) { - struct uAddrSpace *addr = (struct uAddrSpace *)malloc(sizeof(struct uAddrSpace)); + struct uAddrSpace *addr = (struct uAddrSpace *)zalloc(sizeof(struct uAddrSpace)); if (addr == NULL) return NULL; @@ -64,13 +65,23 @@ struct uAddrSpace *uAddrSpaceCreate(struct process *proc) } addr->process = proc; + list_init(addr->listVirtualReg); return addr; } int uAddrSpaceDelete(struct uAddrSpace *addr) { - // TODO Work on Virtual Region + struct uAddrVirtualReg *reg; + + list_collapse_named(addr->listVirtualReg, reg, nextInAddrSpace, prevInAddrSpace) { + // TODO Implement me with real ressources + assertmsg(reg->res == NULL, "Unsupported mapper ressource"); + // This is memory allocated for the heap just unmap it to free it + pr_devel("Freeing heap for process %s\n", processGetName(addr->process)); + pageUnmap(reg->addr); + free(reg); + } return mmuContextUnref(addr->ctx); } @@ -102,30 +113,48 @@ uaddr_t sysBrk(struct uAddrSpace *as, uaddr_t newHeapTop) incSize = ALIGN(newHeapTop - (as->heapStart + as->heapSize), PAGE_SIZE); if (incSize < 0){ - //FIXME + //TODO how to free allocated page by uAddrSpaceCheckNAlloc return as->heapStart + as->heapSize; } as->heapSize += incSize; - return 0; + return as->heapStart + as->heapSize; } int uAddrSpaceCheckNAlloc(struct uAddrSpace *as, vaddr_t addr) { + struct uAddrVirtualReg *newReg; + int right = PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ; + pr_devel("Checking %lx inside %lx and %lx\n", addr, as->heapStart, as->heapStart +as->heapSize); if (addr < as->heapStart || addr >= as->heapStart + as->heapSize) { return -1; } + pr_devel("Alloc heap for process %s\n", processGetName(as->process)); + vaddr_t addrAlign = ALIGN_DOWN(addr, PAGE_SIZE); paddr_t ppage = allocPhyPage(1); - if (0 != pageMap(addrAlign, ppage, PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ)) { - return -1; - } + if (0 != pageMap(addrAlign, ppage, right)) + goto free_ppage; + + newReg = zalloc(sizeof(struct uAddrVirtualReg)); + + if (newReg == NULL) + goto free_ppage; + + newReg->addr = addrAlign; + newReg->size = PAGE_SIZE; + newReg->right = right; + + list_add_tail_named(as->listVirtualReg, newReg, nextInAddrSpace, prevInAddrSpace); unrefPhyPage(ppage); return 0; +free_ppage: + unrefPhyPage(ppage); + return -1; } diff --git a/userspace/libc.c b/userspace/libc.c index e39b93b..80df4e9 100644 --- a/userspace/libc.c +++ b/userspace/libc.c @@ -570,9 +570,26 @@ int readline(char *buf, int size) return i == (size-1); } -void *brk(void *addr) +int brk(void *addr) { - return (void *)syscall1(SYSCALL_ID_BRK, (unsigned int)addr); + uintptr_t new = syscall1(SYSCALL_ID_BRK, (unsigned int)addr); + + //errno = ENOMEM + return (new >= (uintptr_t)addr)?0:-1; + +} + +void *sbrk(intptr_t increment) +{ + void *current = (void *)syscall1(SYSCALL_ID_BRK, 0); + if (increment == 0) { + return current; + } + if (syscall1(SYSCALL_ID_BRK, (uintptr_t)current + increment)) { + // errno = ENOMEM + return (void *)-1; + } + return current; } static char *heapTop = 0; @@ -582,9 +599,9 @@ static char *lastAlloc = 0; void *malloc(size_t size) { if (heapTop == 0) { - heapTop = heapFree = brk(0); + heapTop = heapFree = sbrk(0); } else { - heapTop = brk(0); + heapTop = sbrk(0); } if (heapFree + size + sizeof(size) > heapTop) { diff --git a/userspace/libc.h b/userspace/libc.h index 65097bb..409855c 100644 --- a/userspace/libc.h +++ b/userspace/libc.h @@ -46,6 +46,7 @@ int testSycall5(uint arg1, uint arg2, uint arg3, uint arg4, uint arg5); char readc(); char getchar(); int readline(char *buf, int size); -void *brk(void *addr); +int brk(void *addr); +void *sbrk(intptr_t increment); void *malloc(size_t size); void free(void *ptr); diff --git a/userspace/main_user.c b/userspace/main_user.c index b31292f..f28e678 100644 --- a/userspace/main_user.c +++ b/userspace/main_user.c @@ -26,11 +26,11 @@ int func_alloc() { if (initialHeap == 0) { - initialHeap = brk(0); + initialHeap = sbrk(0); } printf("Testing allocation\n"); int allocSize = 4096 * 2; - char *currentHeap = brk(0); + char *currentHeap = sbrk(0); if (currentHeap - initialHeap < allocSize) { brk(initialHeap + allocSize); } diff --git a/userspace/stdarg.h b/userspace/stdarg.h index 0c96fb7..5760def 100644 --- a/userspace/stdarg.h +++ b/userspace/stdarg.h @@ -42,10 +42,12 @@ typedef enum { FALSE = 0, TRUE } bool_t; typedef unsigned long size_t; typedef long ssize_t; typedef unsigned long int uintptr_t; +typedef long int intptr_t; #else typedef unsigned int size_t; typedef int ssize_t; typedef unsigned int uintptr_t; +typedef int intptr_t; #endif typedef char *va_list;