Add new sample custom_default_heap.

Uses exported function __preinit_user which is called by coreinit to
initialise the default heap before the application is loaded.
This commit is contained in:
James Benton 2018-05-30 19:06:35 +01:00
parent 1489adeb37
commit 6f877a2a3c
3 changed files with 150 additions and 0 deletions

View File

@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.2)
project(custom_default_heap C)
include("${WUT_ROOT}/share/wut.cmake" REQUIRED)
add_executable(custom_default_heap
main.c)
target_link_libraries(custom_default_heap
whb
proc_ui
sysapp)
wut_add_exports(custom_default_heap
exports.def)
wut_create_rpx(custom_default_heap.rpx
custom_default_heap)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/custom_default_heap.rpl"
DESTINATION "${CMAKE_INSTALL_PREFIX}")

View File

@ -0,0 +1,2 @@
:TEXT
__preinit_user

View File

@ -0,0 +1,128 @@
#include <coreinit/dynload.h>
#include <coreinit/memheap.h>
#include <coreinit/memdefaultheap.h>
#include <coreinit/memexpheap.h>
#include <coreinit/memfrmheap.h>
#include <coreinit/memory.h>
#include <coreinit/time.h>
#include <coreinit/systeminfo.h>
#include <whb/proc.h>
#include <whb/log.h>
#include <whb/log_console.h>
static MEMHeapHandle sCustomHeap = NULL;
static uint32_t sCustomHeapAddr = 0;
static uint32_t sCustomHeapSize = 0;
static void *
CustomAllocFromDefaultHeap(uint32_t size)
{
return MEMAllocFromExpHeapEx(sCustomHeap, size, 4);
}
static void *
CustomAllocFromDefaultHeapEx(uint32_t size,
int32_t alignment)
{
return MEMAllocFromExpHeapEx(sCustomHeap, size, alignment);
}
static void
CustomFreeToDefaultHeap(void* ptr)
{
MEMFreeToExpHeap(sCustomHeap, ptr);
}
static OSDynLoad_Error
CustomDynLoadAlloc(int32_t size,
int32_t align,
void **outAddr)
{
if (!outAddr) {
return OS_DYNLOAD_INVALID_ALLOCATOR_PTR;
}
if (align >= 0 && align < 4) {
align = 4;
} else if (align < 0 && align > -4) {
align = -4;
}
if (!(*outAddr = MEMAllocFromDefaultHeapEx(size, align))) {
return OS_DYNLOAD_OUT_OF_MEMORY;
}
return OS_DYNLOAD_OK;
}
static void
CustomDynLoadFree(void *addr)
{
MEMFreeToDefaultHeap(addr);
}
void
__preinit_user(MEMHeapHandle *mem1,
MEMHeapHandle *foreground,
MEMHeapHandle *mem2)
{
uint32_t addr, size;
MEMAllocFromDefaultHeap = CustomAllocFromDefaultHeap;
MEMAllocFromDefaultHeapEx = CustomAllocFromDefaultHeapEx;
MEMFreeToDefaultHeap = CustomFreeToDefaultHeap;
if (OSGetForegroundBucket(NULL, NULL)) {
OSGetMemBound(OS_MEM1, &addr, &size);
*mem1 = MEMCreateFrmHeapEx((void *)addr, size, 0);
OSGetForegroundBucketFreeArea(&addr, &size);
*foreground = MEMCreateFrmHeapEx((void *)addr, size, 0);
}
OSGetMemBound(OS_MEM2, &addr, &size);
sCustomHeap = MEMCreateExpHeapEx((void *)addr, size, MEM_HEAP_FLAG_USE_LOCK);
sCustomHeapAddr = addr;
sCustomHeapSize = size;
*mem2 = sCustomHeap;
OSDynLoad_SetAllocator(CustomDynLoadAlloc, CustomDynLoadFree);
OSDynLoad_SetTLSAllocator(CustomDynLoadAlloc, CustomDynLoadFree);
}
void
heapBlockVisitor(void *block,
MEMHeapHandle heap,
void *context)
{
WHBLogPrintf("Block 0x%08X, size 0x%08X, group 0x%04X, direction %d",
(uint32_t)block,
MEMGetSizeForMBlockExpHeap(block),
MEMGetGroupIDForMBlockExpHeap(block),
MEMGetAllocDirForMBlockExpHeap(block));
}
int
main(int argc, char **argv)
{
WHBProcInit();
WHBLogConsoleInit();
WHBLogPrintf("sCustomHeapAddr = 0x%08X", sCustomHeapAddr);
WHBLogPrintf("sCustomHeapSize = 0x%08X", sCustomHeapSize);
WHBLogPrintf("MEMGetTotalFreeSizeForExpHeap = 0x%08X", MEMGetTotalFreeSizeForExpHeap(sCustomHeap));
WHBLogPrintf("MEMGetAllocatableSizeForExpHeapEx = 0x%08X", MEMGetAllocatableSizeForExpHeapEx(sCustomHeap, 4));
MEMVisitAllocatedForExpHeap(sCustomHeap, heapBlockVisitor, NULL);
while(WHBProcIsRunning()) {
WHBLogConsoleDraw();
OSSleepTicks(OSMillisecondsToTicks(100));
}
WHBLogConsoleFree();
WHBProcShutdown();
return 0;
}