116 lines
3.4 KiB
C
116 lines
3.4 KiB
C
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <exec/debcon.h>
|
|
#include <exec/list.h>
|
|
#include <exec/sync.h>
|
|
#include <exec/mem.h>
|
|
|
|
size_t mem_used = 0;
|
|
size_t mem_total = 0;
|
|
struct List mem_blocks = {0};
|
|
static struct MemBlock *mem_base = (struct MemBlock *)0x100000;
|
|
|
|
static uintptr_t bumppos = 0x1000000;
|
|
|
|
void MemInit(void) {
|
|
NewList(&mem_blocks, LP_BLOCK);
|
|
}
|
|
|
|
struct MemBlock *MarkMem(uintptr_t base, size_t limit, uint8_t flags) {
|
|
/* DOESN'T WORK. BROKEN. */
|
|
|
|
struct MemBlock *block = (struct MemBlock *)(base-sizeof(struct MemBlock));
|
|
struct MemBlock *lastblock = (struct MemBlock *)mem_blocks.head;
|
|
|
|
block->size = limit;
|
|
block->flags = flags;
|
|
|
|
/* find where to insert block */
|
|
while (lastblock->node.next) {
|
|
if (lastblock->node.next == &mem_blocks.tail) {
|
|
/* at last block */
|
|
break;
|
|
}
|
|
if ((uintptr_t)lastblock->node.next + sizeof(struct MemBlock) >= base) {
|
|
/* next block is past base */
|
|
break;
|
|
}
|
|
lastblock = (struct MemBlock *)lastblock->node.next;
|
|
}
|
|
|
|
Insert(&mem_blocks, (struct Node *)block, (struct Node *)lastblock);
|
|
|
|
size_t deltaprev = (uintptr_t)block - (uintptr_t)lastblock - sizeof(struct MemBlock);
|
|
size_t deltanext = lastblock->size - deltaprev - limit;
|
|
|
|
if (deltaprev < lastblock->size) {
|
|
lastblock->size = deltaprev;
|
|
|
|
if (deltanext > 0) {
|
|
struct MemBlock *nextblock = (struct MemBlock *)((uintptr_t)block + sizeof(struct MemBlock) + limit);
|
|
nextblock->size = deltanext;
|
|
nextblock->flags = lastblock->flags;
|
|
}
|
|
}
|
|
|
|
return block;
|
|
}
|
|
|
|
void *AllocMemEx(size_t size, uint8_t flags) {
|
|
#if 0
|
|
struct MemBlock *block = (struct MemBlock *)&mem_blocks.head;
|
|
|
|
while (block->node.next) {
|
|
block = (struct MemBlock *)block->node.next;
|
|
if ((block->flags & 3) == MF_FREE && (block->size >= size)) {
|
|
size_t remaining = block->size - size;
|
|
block->flags &= MF_USED;
|
|
block->size = size;
|
|
mem_used += size;
|
|
if (remaining > sizeof(struct MemBlock)) {
|
|
struct MemBlock *newblock = (struct MemBlock *)((uintptr_t)block + sizeof(struct MemBlock) + size);
|
|
newblock->size = remaining - sizeof(struct MemBlock);
|
|
newblock->flags = MF_FREE;
|
|
Insert(&mem_blocks, (struct Node *)block, (struct Node *)newblock);
|
|
}
|
|
return (void *)((uintptr_t)block + sizeof(struct MemBlock));
|
|
}
|
|
}
|
|
#endif
|
|
/* temporary bump allocator */
|
|
void *addr = (void *)bumppos;
|
|
bumppos += size;
|
|
return addr;
|
|
}
|
|
|
|
void *AllocMem(size_t size) {
|
|
return AllocMemEx(size, 0);
|
|
}
|
|
|
|
void FreeMemEx(void *block, size_t size) {
|
|
|
|
}
|
|
|
|
void FreeMem(void *block) {
|
|
FreeMemEx(block, 0);
|
|
}
|
|
|
|
void PrintMem(void) {
|
|
struct MemBlock *block = (struct MemBlock *)&mem_blocks.head;
|
|
while (block->node.next) {
|
|
block = (struct MemBlock *)block->node.next;
|
|
DebconPrint("Block at ");
|
|
DebconPrintHex((uintptr_t)block);
|
|
DebconPrint(": size ");
|
|
DebconPrintHex(block->size);
|
|
DebconPrint(", flags ");
|
|
DebconPrintHex(block->flags);
|
|
DebconPrint(", next ");
|
|
DebconPrintHex((uint32_t)block->node.next);
|
|
DebconPrint("\n");
|
|
if (block->node.next == &block->node) {
|
|
DebconPrint("Loop detected!\n");
|
|
break;
|
|
}
|
|
}
|
|
} |