Fix memory leak by modifying MMURange in place. Aquire lock for __OSCreateHostThread.

This commit is contained in:
Chris Spegal 2023-08-19 17:23:08 -04:00
parent 0f9d27ae12
commit aa472e13c5
6 changed files with 23 additions and 80 deletions

View file

@ -802,12 +802,11 @@ namespace CafeSystem
sSystemRunning = false; sSystemRunning = false;
} }
void ResumeTitle(bool* runningThreads) void ResumeTitle()
{ {
if (sSystemRunning) if (sSystemRunning)
return; return;
coreinit::ResumeAllThreads();
coreinit::ResumeAllThreads(runningThreads);
sSystemRunning = true; sSystemRunning = true;
} }
@ -824,13 +823,6 @@ namespace CafeSystem
writer.writeData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); writer.writeData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister));
writer.writeData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); writer.writeData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t));
// cpu // cpu
auto threads = coreinit::GetAllThreads();
for (auto& thr : threads)
{
writer.writeBE<bool>(thr != nullptr);
if (thr != nullptr)
writer.writeData(thr, sizeof(OSThread_t));
}
for (auto& thr : activeThread) for (auto& thr : activeThread)
{ {
writer.writeBE(thr); writer.writeBE(thr);
@ -861,19 +853,6 @@ namespace CafeSystem
reader.readData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister)); reader.readData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister));
reader.readData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t)); reader.readData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t));
// cpu // cpu
auto threads = coreinit::GetAllThreads();
for (auto& thr : threads)
{
bool notnull = reader.readBE<bool>();
if (notnull)
{
if (!thr)
{
thr = new OSThread_t;
}
reader.readData(thr, sizeof(OSThread_t));
}
}
for (size_t i = 0; i < 256; i++) for (size_t i = 0; i < 256; i++)
{ {
activeThread[i] = reader.readBE<uint32>(); activeThread[i] = reader.readBE<uint32>();

View file

@ -31,7 +31,7 @@ namespace CafeSystem
void ShutdownTitle(); void ShutdownTitle();
void PauseTitle(); void PauseTitle();
void ResumeTitle(bool* runningThreads = nullptr); void ResumeTitle();
void SaveState(std::string path); void SaveState(std::string path);
void LoadState(std::string path); void LoadState(std::string path);

View file

@ -108,19 +108,15 @@ void MemStreamWriter::writeBE<MMURange>(const MMURange& v)
} }
template <> template <>
MMURange MemStreamReader::readBE<MMURange>() void MemStreamReader::readBE<MMURange>(MMURange& mmuRange)
{ {
bool mapped = readBE<bool>(); mmuRange.m_isMapped = readBE<bool>();
uint32 base = readBE<uint32>(); mmuRange.baseAddress = readBE<uint32>();
MMU_MEM_AREA_ID areaid = (MMU_MEM_AREA_ID)readBE<uint8>(); mmuRange.areaId = (MMU_MEM_AREA_ID)readBE<uint8>();
MMURange::MFLAG flags = (MMURange::MFLAG)readBE<uint8>(); mmuRange.flags = (MMURange::MFLAG)readBE<uint8>();
std::string name = readBE<std::string>(); mmuRange.name = readBE<std::string>();
uint32 size = readBE<uint32>(); mmuRange.size = readBE<uint32>();
uint32 initsize = readBE<uint32>(); mmuRange.initSize = readBE<uint32>();
MMURange range(base, size, areaid, name, flags);
if (mapped)
range.mapMem();
return range;
} }
bool MMURange::deserializeImpl(MemStreamReader& streamReader) bool MMURange::deserializeImpl(MemStreamReader& streamReader)
@ -478,17 +474,14 @@ void memory_Serialize(MemStreamWriter& s)
void memory_Deserialize(MemStreamReader& s) void memory_Deserialize(MemStreamReader& s)
{ {
g_mmuRanges.clear();
size_t cnt = s.readBE<uint64>(); size_t cnt = s.readBE<uint64>();
for (size_t i = 0; i < cnt; i++) for (auto& itr : g_mmuRanges)
{ {
auto range = s.readBE<MMURange>(); s.readBE<MMURange>(*itr);
bool mapped = range.isMapped(); if (itr->isMapped())
if (mapped)
{ {
s.readData(memory_base + range.getBase(), range.getSize()); s.readData(memory_base + itr->getBase(), itr->getSize());
} }
g_mmuRanges.push_back(std::move(&range));
} }
} }

View file

@ -208,53 +208,24 @@ namespace coreinit
OSSuspendThread(ptr); 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) for (auto& thr : activeThread)
{ {
int i = 0;
auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr); auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr);
if (thr != 0) if (thr != 0)
{ {
if (runningThreads && runningThreads[i]) if (s_threadToFiber.find(ptr) == s_threadToFiber.end())
{ {
if (s_threadToFiber.find(ptr) == s_threadToFiber.end()) __OSLockScheduler();
__OSCreateHostThread(ptr); __OSCreateHostThread(ptr);
OSResumeThread(ptr); __OSUnlockScheduler();
}
else if (!runningThreads)
{
if (s_threadToFiber.find(ptr) == s_threadToFiber.end())
__OSCreateHostThread(ptr);
OSResumeThread(ptr);
} }
OSResumeThread(ptr);
} }
i++;
} }
if (__currentCoreThread[0])
OSResumeThread(__currentCoreThread[0]);
if (__currentCoreThread[1])
OSResumeThread(__currentCoreThread[1]);
if (__currentCoreThread[2])
OSResumeThread(__currentCoreThread[2]);
}
std::vector<OSThread_t*> GetAllThreads()
{
auto ret = std::vector<OSThread_t*>();
ret.push_back(__currentCoreThread[0]);
ret.push_back(__currentCoreThread[1]);
ret.push_back(__currentCoreThread[2]);
return ret;
} }
MPTR funcPtr_threadEntry = 0; MPTR funcPtr_threadEntry = 0;

View file

@ -525,8 +525,7 @@ namespace coreinit
sint32 __OSResumeThreadInternal(OSThread_t* thread, sint32 resumeCount); sint32 __OSResumeThreadInternal(OSThread_t* thread, sint32 resumeCount);
sint32 OSResumeThread(OSThread_t* thread); sint32 OSResumeThread(OSThread_t* thread);
void SuspendAllThreads(); void SuspendAllThreads();
void ResumeAllThreads(bool* runningThreads); void ResumeAllThreads();
std::vector<OSThread_t*> GetAllThreads();
void OSContinueThread(OSThread_t* thread); void OSContinueThread(OSThread_t* thread);
void __OSSuspendThreadInternal(OSThread_t* thread); void __OSSuspendThreadInternal(OSThread_t* thread);
void __OSSuspendThreadNolock(OSThread_t* thread); void __OSSuspendThreadNolock(OSThread_t* thread);

View file

@ -9,6 +9,7 @@ public:
} }
template<typename T> T readBE(); template<typename T> T readBE();
template<typename T> void readBE(T& v);
template<typename T> T readLE(); template<typename T> T readLE();
template<typename T> template<typename T>