Implement malloc with a working free #7
@ -5,6 +5,7 @@
|
|||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "mmuContext.h"
|
#include "mmuContext.h"
|
||||||
|
#include "paging.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "stdarg.h"
|
#include "stdarg.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
@ -78,7 +79,7 @@ int uAddrSpaceDelete(struct uAddrSpace *addr)
|
|||||||
// TODO Implement me with real ressources
|
// TODO Implement me with real ressources
|
||||||
assertmsg(reg->res == NULL, "Unsupported mapper ressource");
|
assertmsg(reg->res == NULL, "Unsupported mapper ressource");
|
||||||
// This is memory allocated for the heap just unmap it to free it
|
// This is memory allocated for the heap just unmap it to free it
|
||||||
pr_devel("Freeing heap for process %s\n", processGetName(addr->process));
|
pr_devel("Freeing heap 0x%lx for process %s\n", reg->addr, processGetName(addr->process));
|
||||||
pageUnmap(reg->addr);
|
pageUnmap(reg->addr);
|
||||||
free(reg);
|
free(reg);
|
||||||
}
|
}
|
||||||
@ -127,7 +128,7 @@ int uAddrSpaceCheckNAlloc(struct uAddrSpace *as, vaddr_t addr)
|
|||||||
struct uAddrVirtualReg *newReg;
|
struct uAddrVirtualReg *newReg;
|
||||||
int right = PAGING_MEM_USER | PAGING_MEM_WRITE | PAGING_MEM_READ;
|
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);
|
pr_devel("Checking 0x%lx inside 0x%lx and 0x%lx\n", addr, as->heapStart, as->heapStart +as->heapSize);
|
||||||
if (addr < as->heapStart || addr >= as->heapStart + as->heapSize) {
|
if (addr < as->heapStart || addr >= as->heapStart + as->heapSize) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
do { \
|
do { \
|
||||||
if (!(p)) { \
|
if (!(p)) { \
|
||||||
printf("BUG at %s:%d assert(%s)\n", __FILE__, __LINE__, #p); \
|
printf("BUG at %s:%d assert(%s)\n", __FILE__, __LINE__, #p); \
|
||||||
while (1) { \
|
_exit(-1); \
|
||||||
} \
|
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@ -15,7 +14,6 @@
|
|||||||
if (!(p)) { \
|
if (!(p)) { \
|
||||||
printf("BUG at %s:%d assert(%s)\n", __FILE__, __LINE__, #p); \
|
printf("BUG at %s:%d assert(%s)\n", __FILE__, __LINE__, #p); \
|
||||||
printf(__VA_ARGS__); \
|
printf(__VA_ARGS__); \
|
||||||
while (1) { \
|
_exit(-1); \
|
||||||
} \
|
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
|
#include "list.h"
|
||||||
#include "minmax.h"
|
#include "minmax.h"
|
||||||
#include "swintr.h"
|
#include "swintr.h"
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
@ -585,45 +586,90 @@ void *sbrk(intptr_t increment)
|
|||||||
if (increment == 0) {
|
if (increment == 0) {
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
if (syscall1(SYSCALL_ID_BRK, (uintptr_t)current + increment)) {
|
if ((uintptr_t)syscall1(SYSCALL_ID_BRK, (uintptr_t)current + increment) < ((uintptr_t)current + increment)) {
|
||||||
// errno = ENOMEM
|
// errno = ENOMEM
|
||||||
return (void *)-1;
|
return (void *)-1;
|
||||||
}
|
}
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *heapTop = 0;
|
// Malloc internal
|
||||||
static char *heapFree = 0;
|
struct heapBlock {
|
||||||
static char *lastAlloc = 0;
|
size_t size;
|
||||||
|
struct heapBlock *next, *prev;
|
||||||
|
int free;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct heapBlock *heapBlkList = NULL;
|
||||||
|
|
||||||
|
struct heapBlock *findFreeBlock(size_t size){
|
||||||
|
struct heapBlock *cur = NULL;
|
||||||
|
struct heapBlock *found = NULL;
|
||||||
|
int idx;
|
||||||
|
list_foreach(heapBlkList, cur, idx){
|
||||||
|
if(cur->size >= size && cur->free){
|
||||||
|
found = cur;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct heapBlock *allocNewBlock(size_t size) {
|
||||||
|
struct heapBlock *blk = sbrk(size + sizeof(struct heapBlock));
|
||||||
|
struct heapBlock *head = sbrk(0);
|
||||||
|
size_t blkSize = (intptr_t)head - (intptr_t)blk - sizeof(struct heapBlock);
|
||||||
|
if (blk == (void *)-1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
blk->size = blkSize;
|
||||||
|
blk->free = 1;
|
||||||
|
list_add_tail(heapBlkList, blk);
|
||||||
|
return blk;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct heapBlock *splitBlock(struct heapBlock *blk, size_t neededSize)
|
||||||
|
{
|
||||||
|
if (blk->size < neededSize + sizeof(struct heapBlock) + 1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
struct heapBlock *newBlk = (struct heapBlock *)((uintptr_t)(blk + 1) + neededSize);
|
||||||
|
newBlk->free = 1;
|
||||||
|
newBlk->size = blk->size - sizeof(struct heapBlock) - neededSize;
|
||||||
|
blk->size = neededSize;
|
||||||
|
return newBlk;
|
||||||
|
}
|
||||||
|
|
||||||
void *malloc(size_t size)
|
void *malloc(size_t size)
|
||||||
{
|
{
|
||||||
if (heapTop == 0) {
|
if (size == 0)
|
||||||
heapTop = heapFree = sbrk(0);
|
|
||||||
} else {
|
|
||||||
heapTop = sbrk(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (heapFree + size + sizeof(size) > heapTop) {
|
|
||||||
if (brk(heapTop + size + sizeof(size)))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
struct heapBlock *blk = findFreeBlock(size);
|
||||||
|
if (!blk)
|
||||||
|
blk = allocNewBlock(size);
|
||||||
|
if (!blk)
|
||||||
|
return NULL;
|
||||||
|
struct heapBlock *remainBlock = splitBlock(blk, size);
|
||||||
|
if (remainBlock) {
|
||||||
|
list_add_head(heapBlkList, remainBlock);
|
||||||
|
}
|
||||||
|
blk->free = 0;
|
||||||
|
return blk + 1; // return the area after the blk description
|
||||||
}
|
}
|
||||||
|
|
||||||
*((size_t *)heapFree) = size;
|
struct heapBlock *getHeapBlock(void *ptr) {
|
||||||
heapFree += sizeof(size);
|
return (struct heapBlock *)ptr - 1;
|
||||||
lastAlloc = heapFree;
|
|
||||||
heapFree += size;
|
|
||||||
return lastAlloc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void free(void *ptr)
|
|
||||||
{
|
|
||||||
void *size_addr = ((char *)ptr - sizeof(size_t));
|
|
||||||
size_t size = *(size_t *)size_addr;
|
|
||||||
if (heapFree - size == ptr) {
|
|
||||||
heapFree = size_addr;
|
|
||||||
}
|
|
||||||
//TODO ELSE
|
|
||||||
|
|
||||||
|
void free(void *ptr){
|
||||||
|
if(!ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
struct heapBlock *blk = getHeapBlock(ptr);
|
||||||
|
|
||||||
|
assert(blk->free == 0);
|
||||||
|
blk->free = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ int func_suicide()
|
|||||||
char *initialHeap = 0;
|
char *initialHeap = 0;
|
||||||
int func_alloc()
|
int func_alloc()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (initialHeap == 0) {
|
if (initialHeap == 0) {
|
||||||
initialHeap = sbrk(0);
|
initialHeap = sbrk(0);
|
||||||
}
|
}
|
||||||
@ -38,7 +37,20 @@ int func_alloc()
|
|||||||
for (unsigned int i = 0; i < allocSize / sizeof(int); i++) {
|
for (unsigned int i = 0; i < allocSize / sizeof(int); i++) {
|
||||||
allocatedData[i] = i;
|
allocatedData[i] = i;
|
||||||
}
|
}
|
||||||
printf("Success\n");
|
printf("Success\nTesting malloc\n");
|
||||||
|
uintptr_t heap = (uintptr_t)sbrk(0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
void *ptr = malloc(1 << i);
|
||||||
|
printf("malloc size %d: 0x%p\n", (1 << i), ptr);
|
||||||
|
if (ptr == NULL) {
|
||||||
|
printf("Malloc failed\n");
|
||||||
|
}
|
||||||
|
memset(ptr, 0, 1 << i);
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
uintptr_t newHeap = (uintptr_t)sbrk(0);
|
||||||
|
printf("Malloc used %dB\n", newHeap - heap);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user