Revamp mappableAlloc
This commit is contained in:
parent
e86e906895
commit
6433798f06
@ -4,27 +4,24 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <3ds/types.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reserves a mappable memory area.
|
* @brief Initializes the mappable allocator.
|
||||||
* @param size Size of the area to reserve.
|
* @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.
|
* @return The mappable area.
|
||||||
*/
|
*/
|
||||||
void* mappableAlloc(size_t size);
|
void* mappableAlloc(size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieves the allocated size of a mappable area.
|
* @brief Frees a mappable area (stubbed).
|
||||||
* @return The size of the mappable area.
|
|
||||||
*/
|
|
||||||
size_t mappableGetSize(void* mem);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Frees a mappable area.
|
|
||||||
* @param mem Mappable area to free.
|
* @param mem Mappable area to free.
|
||||||
*/
|
*/
|
||||||
void mappableFree(void* mem);
|
void mappableFree(void* mem);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Gets the current mappable free space.
|
|
||||||
* @return The current mappable free space.
|
|
||||||
*/
|
|
||||||
u32 mappableSpaceFree(void);
|
|
||||||
|
59
libctru/source/allocator/mappable.c
Normal file
59
libctru/source/allocator/mappable.c
Normal 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;
|
||||||
|
}
|
@ -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();
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
#include <3ds/types.h>
|
|
||||||
#include <3ds/svc.h>
|
#include <3ds/svc.h>
|
||||||
|
#include <3ds/allocator/mappable.h>
|
||||||
#include <3ds/env.h>
|
#include <3ds/env.h>
|
||||||
#include <3ds/os.h>
|
#include <3ds/os.h>
|
||||||
|
|
||||||
@ -39,6 +39,9 @@ void __attribute__((weak)) __system_allocateHeaps(void) {
|
|||||||
// Allocate the linear heap
|
// Allocate the linear heap
|
||||||
svcControlMemory(&__ctru_linear_heap, 0x0, 0x0, __ctru_linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
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
|
// Set up newlib heap
|
||||||
fake_heap_start = (char*)__ctru_heap;
|
fake_heap_start = (char*)__ctru_heap;
|
||||||
fake_heap_end = fake_heap_start + __ctru_heap_size;
|
fake_heap_end = fake_heap_start + __ctru_heap_size;
|
||||||
|
Loading…
Reference in New Issue
Block a user