mirror of
https://github.com/wiiu-env/MemoryMappingModule.git
synced 2024-11-25 11:16:53 +01:00
Use the default heap for threads, make sure to memset default heap allocations to 0 after using them
This commit is contained in:
parent
6076c8726c
commit
f2333e37dc
@ -1,4 +1,4 @@
|
|||||||
FROM ghcr.io/wiiu-env/devkitppc:20221228
|
FROM ghcr.io/wiiu-env/devkitppc:20230326
|
||||||
|
|
||||||
COPY --from=ghcr.io/wiiu-env/libkernel:20220904 /artifacts $DEVKITPRO
|
COPY --from=ghcr.io/wiiu-env/libkernel:20220904 /artifacts $DEVKITPRO
|
||||||
COPY --from=ghcr.io/wiiu-env/libfunctionpatcher:20230106 /artifacts $DEVKITPRO
|
COPY --from=ghcr.io/wiiu-env/libfunctionpatcher:20230106 /artifacts $DEVKITPRO
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
#include <coreinit/thread.h>
|
#include <coreinit/thread.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -26,14 +28,15 @@ public:
|
|||||||
typedef void (*Callback)(CThread *thread, void *arg);
|
typedef void (*Callback)(CThread *thread, void *arg);
|
||||||
|
|
||||||
//! constructor
|
//! constructor
|
||||||
explicit CThread(int32_t iAttr, int32_t iPriority = 16, int32_t iStackSize = 0x8000, CThread::Callback callback = nullptr, void *callbackArg = nullptr)
|
explicit CThread(int32_t iAttr, int32_t iPriority = 16, int32_t stacksize = 0x8000, CThread::Callback callback = nullptr, void *callbackArg = nullptr)
|
||||||
: pThread(nullptr), pThreadStack(nullptr), pCallback(callback), pCallbackArg(callbackArg) {
|
: pThread(nullptr), pThreadStack(nullptr), pCallback(callback), pCallbackArg(callbackArg) {
|
||||||
//! save attribute assignment
|
//! save attribute assignment
|
||||||
iAttributes = iAttr;
|
iAttributes = iAttr;
|
||||||
//! allocate the thread
|
iStackSize = stacksize;
|
||||||
pThread = (OSThread *) memalign(8, 0x1000);
|
//! allocate the thread on the default Cafe OS heap
|
||||||
//! allocate the stack
|
pThread = (OSThread *) gMEMAllocFromDefaultHeapExForThreads(sizeof(OSThread), 0x10);
|
||||||
pThreadStack = (uint8_t *) memalign(0x20, iStackSize);
|
//! allocate the stack on the default Cafe OS heap
|
||||||
|
pThreadStack = (uint8_t *) gMEMAllocFromDefaultHeapExForThreads(iStackSize, 0x20);
|
||||||
//! create the thread
|
//! create the thread
|
||||||
if (pThread && pThreadStack) {
|
if (pThread && pThreadStack) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@ -71,7 +74,9 @@ public:
|
|||||||
//! Resume thread
|
//! Resume thread
|
||||||
virtual void resumeThread() {
|
virtual void resumeThread() {
|
||||||
if (!isThreadSuspended()) return;
|
if (!isThreadSuspended()) return;
|
||||||
if (pThread) OSResumeThread(pThread);
|
if (pThread) {
|
||||||
|
OSResumeThread(pThread);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Set thread priority
|
//! Set thread priority
|
||||||
@ -111,12 +116,16 @@ public:
|
|||||||
}
|
}
|
||||||
OSJoinThread(pThread, nullptr);
|
OSJoinThread(pThread, nullptr);
|
||||||
}
|
}
|
||||||
|
// Some games (e.g. Minecraft) expect the default heap to be empty.
|
||||||
|
// Make sure to clean up the memory after using it
|
||||||
//! free the thread stack buffer
|
//! free the thread stack buffer
|
||||||
if (pThreadStack) {
|
if (pThreadStack) {
|
||||||
free(pThreadStack);
|
memset(pThreadStack, 0, iStackSize);
|
||||||
|
gMEMFreeToDefaultHeapForThreads(pThreadStack);
|
||||||
}
|
}
|
||||||
if (pThread) {
|
if (pThread) {
|
||||||
free(pThread);
|
memset(pThread, 0, sizeof(OSThread));
|
||||||
|
gMEMFreeToDefaultHeapForThreads(pThread);
|
||||||
}
|
}
|
||||||
pThread = nullptr;
|
pThread = nullptr;
|
||||||
pThreadStack = nullptr;
|
pThreadStack = nullptr;
|
||||||
@ -139,6 +148,7 @@ private:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t iStackSize;
|
||||||
int32_t iAttributes;
|
int32_t iAttributes;
|
||||||
OSThread *pThread;
|
OSThread *pThread;
|
||||||
uint8_t *pThreadStack;
|
uint8_t *pThreadStack;
|
||||||
|
4
source/globals.c
Normal file
4
source/globals.c
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
void *(*gMEMAllocFromDefaultHeapExForThreads)(uint32_t size, int align);
|
||||||
|
void (*gMEMFreeToDefaultHeapForThreads)(void *ptr);
|
5
source/globals.h
Normal file
5
source/globals.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern void *(*gMEMAllocFromDefaultHeapExForThreads)(uint32_t size, int align);
|
||||||
|
extern void (*gMEMFreeToDefaultHeapForThreads)(void *ptr);
|
@ -1,4 +1,6 @@
|
|||||||
#include "function_replacements.h"
|
#include "function_replacements.h"
|
||||||
|
#include "globals.h"
|
||||||
|
#include "logger.h"
|
||||||
#include "memory_mapping.h"
|
#include "memory_mapping.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include <coreinit/debug.h>
|
#include <coreinit/debug.h>
|
||||||
@ -16,15 +18,45 @@ WUMS_MODULE_INIT_BEFORE_RELOCATION_DONE_HOOK();
|
|||||||
WUMS_DEPENDS_ON(homebrew_kernel);
|
WUMS_DEPENDS_ON(homebrew_kernel);
|
||||||
WUMS_DEPENDS_ON(homebrew_functionpatcher);
|
WUMS_DEPENDS_ON(homebrew_functionpatcher);
|
||||||
|
|
||||||
|
#include <coreinit/dynload.h>
|
||||||
|
#include <coreinit/memdefaultheap.h>
|
||||||
|
|
||||||
// We can't use the functions from libfunctionpatcher. Defined in functionpatcher.def
|
// We can't use the functions from libfunctionpatcher. Defined in functionpatcher.def
|
||||||
extern "C" FunctionPatcherStatus FPAddFunctionPatch(function_replacement_data_t *function_data, PatchedFunctionHandle *outHandle, bool *outHasBeenPatched);
|
extern "C" FunctionPatcherStatus FPAddFunctionPatch(function_replacement_data_t *function_data, PatchedFunctionHandle *outHandle, bool *outHasBeenPatched);
|
||||||
|
|
||||||
|
void UpdateFunctionPointer() {
|
||||||
|
// We need the real MEMAllocFromDefaultHeapEx/MEMFreeToDefaultHeap function pointer to force-allocate memory on the default heap.
|
||||||
|
// Our custom heap doesn't work (yet) for threads and causes an app panic.
|
||||||
|
OSDynLoad_Module coreinitModule;
|
||||||
|
if (OSDynLoad_Acquire("coreinit", &coreinitModule) != OS_DYNLOAD_OK) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Failed to acquire coreinit.rpl");
|
||||||
|
OSFatal("FunctionPatcherModule: Failed to acquire coreinit.rpl");
|
||||||
|
}
|
||||||
|
/* Memory allocation functions */
|
||||||
|
uint32_t *allocPtr, *freePtr;
|
||||||
|
if (OSDynLoad_FindExport(coreinitModule, OS_DYNLOAD_EXPORT_DATA, "MEMAllocFromDefaultHeapEx", reinterpret_cast<void **>(&allocPtr)) != OS_DYNLOAD_OK) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("OSDynLoad_FindExport for MEMAllocFromDefaultHeapEx");
|
||||||
|
OSFatal("MemoryMappingModule: OSDynLoad_FindExport for MEMAllocFromDefaultHeapEx");
|
||||||
|
}
|
||||||
|
if (OSDynLoad_FindExport(coreinitModule, OS_DYNLOAD_EXPORT_DATA, "MEMFreeToDefaultHeap", reinterpret_cast<void **>(&freePtr)) != OS_DYNLOAD_OK) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("OSDynLoad_FindExport for MEMFreeToDefaultHeap");
|
||||||
|
OSFatal("MemoryMappingModule: OSDynLoad_FindExport for MEMFreeToDefaultHeap");
|
||||||
|
}
|
||||||
|
|
||||||
|
gMEMAllocFromDefaultHeapExForThreads = (void *(*) (uint32_t, int) ) * allocPtr;
|
||||||
|
gMEMFreeToDefaultHeapForThreads = (void (*)(void *)) * freePtr;
|
||||||
|
|
||||||
|
OSDynLoad_Release(coreinitModule);
|
||||||
|
}
|
||||||
|
|
||||||
WUMS_INITIALIZE(args) {
|
WUMS_INITIALIZE(args) {
|
||||||
static uint8_t ucSetupRequired = 1;
|
static uint8_t ucSetupRequired = 1;
|
||||||
if (!ucSetupRequired) {
|
if (!ucSetupRequired) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateFunctionPointer();
|
||||||
|
|
||||||
ucSetupRequired = 0;
|
ucSetupRequired = 0;
|
||||||
MemoryMapping_setupMemoryMapping();
|
MemoryMapping_setupMemoryMapping();
|
||||||
MemoryMapping_CreateHeaps();
|
MemoryMapping_CreateHeaps();
|
||||||
@ -45,6 +77,11 @@ WUMS_INITIALIZE(args) {
|
|||||||
|
|
||||||
WUMS_APPLICATION_STARTS() {
|
WUMS_APPLICATION_STARTS() {
|
||||||
OSReport("Running MemoryMappingModule " VERSION VERSION_EXTRA "\n");
|
OSReport("Running MemoryMappingModule " VERSION VERSION_EXTRA "\n");
|
||||||
|
|
||||||
|
// Now we can update the pointer with the "real" functions
|
||||||
|
gMEMAllocFromDefaultHeapExForThreads = MEMAllocFromDefaultHeapEx;
|
||||||
|
gMEMFreeToDefaultHeapForThreads = MEMFreeToDefaultHeap;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
initLogging();
|
initLogging();
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user