From 6433798f06edecb464bf46dcca76cc308af90e52 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Wed, 13 May 2020 19:01:56 +0100 Subject: [PATCH] Revamp mappableAlloc --- libctru/include/3ds/allocator/mappable.h | 27 +++++----- libctru/source/allocator/mappable.c | 59 +++++++++++++++++++++ libctru/source/allocator/mappable.cpp | 67 ------------------------ libctru/source/system/allocateHeaps.c | 5 +- 4 files changed, 75 insertions(+), 83 deletions(-) create mode 100644 libctru/source/allocator/mappable.c delete mode 100644 libctru/source/allocator/mappable.cpp diff --git a/libctru/include/3ds/allocator/mappable.h b/libctru/include/3ds/allocator/mappable.h index 6fabe93..fb57dc1 100644 --- a/libctru/include/3ds/allocator/mappable.h +++ b/libctru/include/3ds/allocator/mappable.h @@ -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); diff --git a/libctru/source/allocator/mappable.c b/libctru/source/allocator/mappable.c new file mode 100644 index 0000000..de770cf --- /dev/null +++ b/libctru/source/allocator/mappable.c @@ -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; +} diff --git a/libctru/source/allocator/mappable.cpp b/libctru/source/allocator/mappable.cpp deleted file mode 100644 index c75d7cd..0000000 --- a/libctru/source/allocator/mappable.cpp +++ /dev/null @@ -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(); -} diff --git a/libctru/source/system/allocateHeaps.c b/libctru/source/system/allocateHeaps.c index fdb2ac8..d35b4d6 100644 --- a/libctru/source/system/allocateHeaps.c +++ b/libctru/source/system/allocateHeaps.c @@ -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;