From aa472e13c57c9b1c0cc7855772310fdf971e698b Mon Sep 17 00:00:00 2001 From: Chris Spegal Date: Sat, 19 Aug 2023 17:23:08 -0400 Subject: [PATCH] Fix memory leak by modifying MMURange in place. Aquire lock for __OSCreateHostThread. --- src/Cafe/CafeSystem.cpp | 25 +---------- src/Cafe/CafeSystem.h | 2 +- src/Cafe/HW/MMU/MMU.cpp | 31 ++++++-------- src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp | 41 +++---------------- src/Cafe/OS/libs/coreinit/coreinit_Thread.h | 3 +- src/util/helpers/Serializer.h | 1 + 6 files changed, 23 insertions(+), 80 deletions(-) diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index 3ebc86a7..b81b3681 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -802,12 +802,11 @@ namespace CafeSystem sSystemRunning = false; } - void ResumeTitle(bool* runningThreads) + void ResumeTitle() { if (sSystemRunning) return; - - coreinit::ResumeAllThreads(runningThreads); + coreinit::ResumeAllThreads(); sSystemRunning = true; } @@ -824,13 +823,6 @@ namespace CafeSystem writer.writeData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); writer.writeData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); // cpu - auto threads = coreinit::GetAllThreads(); - for (auto& thr : threads) - { - writer.writeBE(thr != nullptr); - if (thr != nullptr) - writer.writeData(thr, sizeof(OSThread_t)); - } for (auto& thr : activeThread) { writer.writeBE(thr); @@ -861,19 +853,6 @@ namespace CafeSystem reader.readData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); reader.readData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); // cpu - auto threads = coreinit::GetAllThreads(); - for (auto& thr : threads) - { - bool notnull = reader.readBE(); - if (notnull) - { - if (!thr) - { - thr = new OSThread_t; - } - reader.readData(thr, sizeof(OSThread_t)); - } - } for (size_t i = 0; i < 256; i++) { activeThread[i] = reader.readBE(); diff --git a/src/Cafe/CafeSystem.h b/src/Cafe/CafeSystem.h index 8be2355d..db5f1dc4 100644 --- a/src/Cafe/CafeSystem.h +++ b/src/Cafe/CafeSystem.h @@ -31,7 +31,7 @@ namespace CafeSystem void ShutdownTitle(); void PauseTitle(); - void ResumeTitle(bool* runningThreads = nullptr); + void ResumeTitle(); void SaveState(std::string path); void LoadState(std::string path); diff --git a/src/Cafe/HW/MMU/MMU.cpp b/src/Cafe/HW/MMU/MMU.cpp index e6b47838..eec61b8b 100644 --- a/src/Cafe/HW/MMU/MMU.cpp +++ b/src/Cafe/HW/MMU/MMU.cpp @@ -108,19 +108,15 @@ void MemStreamWriter::writeBE(const MMURange& v) } template <> -MMURange MemStreamReader::readBE() +void MemStreamReader::readBE(MMURange& mmuRange) { - bool mapped = readBE(); - uint32 base = readBE(); - MMU_MEM_AREA_ID areaid = (MMU_MEM_AREA_ID)readBE(); - MMURange::MFLAG flags = (MMURange::MFLAG)readBE(); - std::string name = readBE(); - uint32 size = readBE(); - uint32 initsize = readBE(); - MMURange range(base, size, areaid, name, flags); - if (mapped) - range.mapMem(); - return range; + mmuRange.m_isMapped = readBE(); + mmuRange.baseAddress = readBE(); + mmuRange.areaId = (MMU_MEM_AREA_ID)readBE(); + mmuRange.flags = (MMURange::MFLAG)readBE(); + mmuRange.name = readBE(); + mmuRange.size = readBE(); + mmuRange.initSize = readBE(); } bool MMURange::deserializeImpl(MemStreamReader& streamReader) @@ -478,17 +474,14 @@ void memory_Serialize(MemStreamWriter& s) void memory_Deserialize(MemStreamReader& s) { - g_mmuRanges.clear(); size_t cnt = s.readBE(); - for (size_t i = 0; i < cnt; i++) + for (auto& itr : g_mmuRanges) { - auto range = s.readBE(); - bool mapped = range.isMapped(); - if (mapped) + s.readBE(*itr); + if (itr->isMapped()) { - s.readData(memory_base + range.getBase(), range.getSize()); + s.readData(memory_base + itr->getBase(), itr->getSize()); } - g_mmuRanges.push_back(std::move(&range)); } } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp index ab82175b..6724ee5f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp @@ -208,53 +208,24 @@ namespace coreinit OSSuspendThread(ptr); } } - if (__currentCoreThread[0]) - OSSuspendThread(__currentCoreThread[0]); - if (__currentCoreThread[1]) - OSSuspendThread(__currentCoreThread[1]); - if (__currentCoreThread[2]) - OSSuspendThread(__currentCoreThread[2]); - } - void ResumeAllThreads(bool* runningThreads) + void ResumeAllThreads() { for (auto& thr : activeThread) { - int i = 0; auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr); if (thr != 0) { - if (runningThreads && runningThreads[i]) + if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) { - if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) - __OSCreateHostThread(ptr); - OSResumeThread(ptr); - } - else if (!runningThreads) - { - if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) - __OSCreateHostThread(ptr); - OSResumeThread(ptr); + __OSLockScheduler(); + __OSCreateHostThread(ptr); + __OSUnlockScheduler(); } + OSResumeThread(ptr); } - i++; } - if (__currentCoreThread[0]) - OSResumeThread(__currentCoreThread[0]); - if (__currentCoreThread[1]) - OSResumeThread(__currentCoreThread[1]); - if (__currentCoreThread[2]) - OSResumeThread(__currentCoreThread[2]); - } - - std::vector GetAllThreads() - { - auto ret = std::vector(); - ret.push_back(__currentCoreThread[0]); - ret.push_back(__currentCoreThread[1]); - ret.push_back(__currentCoreThread[2]); - return ret; } MPTR funcPtr_threadEntry = 0; diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h index d04b8ee4..bac966a2 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h @@ -525,8 +525,7 @@ namespace coreinit sint32 __OSResumeThreadInternal(OSThread_t* thread, sint32 resumeCount); sint32 OSResumeThread(OSThread_t* thread); void SuspendAllThreads(); - void ResumeAllThreads(bool* runningThreads); - std::vector GetAllThreads(); + void ResumeAllThreads(); void OSContinueThread(OSThread_t* thread); void __OSSuspendThreadInternal(OSThread_t* thread); void __OSSuspendThreadNolock(OSThread_t* thread); diff --git a/src/util/helpers/Serializer.h b/src/util/helpers/Serializer.h index a4941c29..1c7bbce1 100644 --- a/src/util/helpers/Serializer.h +++ b/src/util/helpers/Serializer.h @@ -9,6 +9,7 @@ public: } template T readBE(); + template void readBE(T& v); template T readLE(); template