Revamp mappableAlloc

This commit is contained in:
TuxSH 2020-05-13 19:01:56 +01:00 committed by fincs
parent c9326f6bce
commit 69483a473a
4 changed files with 75 additions and 83 deletions

View File

@ -4,27 +4,24 @@
*/
#pragma once
#include <3ds/types.h>
/**
* @brief Reserves a mappable memory area.
* @param size Size of the area to reserve.
* @brief Initializes the mappable allocator.
* @param addrMin Minimum address.
* @param addrMax Maxium address.
*/
void mappableInit(u32 addrMin, u32 addrMax);
/**
* @brief Finds a mappable memory area.
* @param size Size of the area to find.
* @return The mappable area.
*/
void* mappableAlloc(size_t size);
/**
* @brief Retrieves the allocated size of a mappable area.
* @return The size of the mappable area.
*/
size_t mappableGetSize(void* mem);
/**
* @brief Frees a mappable area.
* @brief Frees a mappable area (stubbed).
* @param mem Mappable area to free.
*/
void mappableFree(void* mem);
/**
* @brief Gets the current mappable free space.
* @return The current mappable free space.
*/
u32 mappableSpaceFree(void);

View File

@ -0,0 +1,59 @@
#include <3ds/allocator/mappable.h>
#include <3ds/svc.h>
#include <3ds/result.h>
static u32 minAddr, maxAddr, currentAddr;
void mappableInit(u32 addrMin, u32 addrMax)
{
minAddr = addrMin;
maxAddr = addrMax;
currentAddr = minAddr;
}
static u32 mappableFindAddressWithin(u32 start, u32 end, u32 size)
{
MemInfo info;
PageInfo pgInfo;
u32 addr = start;
while (addr >= start && (addr + size) < end && (addr + size) >= addr)
{
if (R_FAILED(svcQueryMemory(&info, &pgInfo, addr)))
return 0;
if (info.state == MEMSTATE_FREE)
{
u32 sz = info.size - (addr - info.base_addr); // a free block might cover all the memory, etc.
if (sz >= size)
return addr;
}
addr = info.base_addr + info.size;
}
return 0;
}
void* mappableAlloc(size_t size)
{
// Round up, can only allocate in page units
size = (size + 0xFFF) & ~0xFFF;
u32 addr = mappableFindAddressWithin(currentAddr, maxAddr, size);
if (addr == 0)
{
// Need to rollover (maybe)
addr = mappableFindAddressWithin(minAddr, currentAddr, size);
if (addr == 0)
return NULL;
}
currentAddr = addr + size >= maxAddr ? minAddr : addr + size;
return (void *)addr;
}
void mappableFree(void* mem)
{
(void)mem;
}

View File

@ -1,67 +0,0 @@
extern "C"
{
#include <3ds/types.h>
#include <3ds/allocator/mappable.h>
#include <3ds/util/rbtree.h>
}
#include "mem_pool.h"
#include "addrmap.h"
static MemPool sMappablePool;
static bool mappableInit()
{
auto blk = MemBlock::Create((u8*)0x10000000, 0x04000000);
if (blk)
{
sMappablePool.AddBlock(blk);
rbtree_init(&sAddrMap, addrMapNodeComparator);
return true;
}
return false;
}
void* mappableAlloc(size_t size)
{
// Initialize the pool if it is not ready
if (!sMappablePool.Ready() && !mappableInit())
return nullptr;
// Allocate the chunk
MemChunk chunk;
if (!sMappablePool.Allocate(chunk, size, 12))
return nullptr;
auto node = newNode(chunk);
if (!node)
{
sMappablePool.Deallocate(chunk);
return nullptr;
}
if (rbtree_insert(&sAddrMap, &node->node));
return chunk.addr;
}
size_t mappableGetSize(void* mem)
{
auto node = getNode(mem);
return node ? node->chunk.size : 0;
}
void mappableFree(void* mem)
{
auto node = getNode(mem);
if (!node) return;
// Free the chunk
sMappablePool.Deallocate(node->chunk);
// Free the node
delNode(node);
}
u32 mappableSpaceFree()
{
return sMappablePool.GetFreeSpace();
}

View File

@ -1,5 +1,5 @@
#include <3ds/types.h>
#include <3ds/svc.h>
#include <3ds/allocator/mappable.h>
#include <3ds/env.h>
#include <3ds/os.h>
@ -39,6 +39,9 @@ void __attribute__((weak)) __system_allocateHeaps(void) {
// Allocate the linear heap
svcControlMemory(&__ctru_linear_heap, 0x0, 0x0, __ctru_linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
// Mappable allocator init
mappableInit(0x10000000, 0x14000000);
// Set up newlib heap
fake_heap_start = (char*)__ctru_heap;
fake_heap_end = fake_heap_start + __ctru_heap_size;