Created
December 22, 2022 14:49
-
-
Save LibretroAdmin/ed7b65f8283483a3b42fba17ac37ab8b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/libretro/main.cpp b/libretro/main.cpp | |
index 2d9bef353..033981238 100644 | |
--- a/libretro/main.cpp | |
+++ b/libretro/main.cpp | |
@@ -53,7 +53,8 @@ static struct retro_perf_callback perf_cb; | |
#endif | |
static bool libretro_supports_option_categories = false; | |
-static bool init_failed = false; | |
+bool libretro_init = true; | |
+bool libretro_deinit = false; | |
int option_upscale_mult = 1; | |
int option_pad_left_deadzone = 0; | |
int option_pad_right_deadzone = 0; | |
@@ -420,27 +421,33 @@ void retro_init(void) | |
} | |
else | |
- init_failed = true; | |
+ libretro_init = false; | |
+ | |
+ libretro_deinit = false; | |
} | |
void retro_deinit(void) | |
{ | |
libretro_supports_option_categories = false; | |
- | |
- /* FIXME: This is a workaround that resolves crashes on close content. | |
- When closing the frontend, we end up with a zombie process because the | |
- main thread tries to call vu1Thread.Cancel() within pcsx2's destructor | |
- and it gets stuck waiting for a mutex that will never unlock */ | |
- vu1Thread.WaitVU(); | |
- //vu1Thread.Cancel(); | |
- | |
- pcsx2->CleanupOnExit(); | |
- pcsx2->OnExit(); | |
+ libretro_init = true; | |
+ libretro_deinit = true; | |
bios_files.clear(); | |
custom_memcard_list_slot1.clear(); | |
custom_memcard_list_slot2.clear(); | |
+ vu1Thread.WaitVU(); | |
+ vu1Thread.Cancel(); | |
+ GetMTGS().Cancel(); | |
+ | |
+ GetMTGS().FinishTaskInThread(); | |
+ //CoreThread.Cancel(); | |
+ | |
+ //pcsx2->CleanupOnExit(); | |
+ //pcsx2->OnExit(); | |
+ pcsx2->Exit(); | |
+ wxTheApp->Exit(); | |
+ | |
#ifdef PERF_TEST | |
perf_cb.perf_log(); | |
#endif | |
@@ -490,8 +497,14 @@ void retro_get_system_av_info(retro_system_av_info* info) | |
void retro_reset(void) | |
{ | |
+ vu1Thread.WaitVU(); | |
+ vu1Thread.Cancel(); | |
+ GetMTGS().Cancel(); | |
+ | |
GetMTGS().FinishTaskInThread(); | |
GetCoreThread().ResetQuick(); | |
+ GetCoreThread().Resume(); | |
+ | |
DiskControl::eject_state = false; | |
} | |
@@ -513,7 +526,6 @@ static void context_destroy(void) | |
static bool set_hw_render(retro_hw_context_type type) | |
{ | |
- | |
hw_render.context_type = type; | |
hw_render.context_reset = context_reset; | |
hw_render.context_destroy = context_destroy; | |
@@ -614,9 +626,9 @@ read_m3u_file(const wxFileName& m3u_file) | |
bool retro_load_game(const struct retro_game_info* game) | |
{ | |
- if (init_failed) | |
+ if (!libretro_init) | |
{ | |
- init_failed = false; | |
+ libretro_init = true; | |
return false; | |
} | |
@@ -852,19 +864,9 @@ bool retro_load_game_special(unsigned game_type, const struct retro_game_info* i | |
void retro_unload_game(void) | |
{ | |
- // GetMTGS().FinishTaskInThread(); | |
- // GetMTGS().CloseGS(); | |
- GetMTGS().FinishTaskInThread(); | |
- | |
- while (pcsx2->HasPendingEvents()) | |
- pcsx2->ProcessPendingEvents(); | |
- GetMTGS().CloseGS(); | |
- | |
- while (pcsx2->HasPendingEvents()) | |
- pcsx2->ProcessPendingEvents(); | |
+ context_destroy(); | |
} | |
- | |
void retro_run(void) | |
{ | |
bool updated = false; | |
diff --git a/pcsx2/MTGS.cpp b/pcsx2/MTGS.cpp | |
index cc5a7cce1..4818649b1 100644 | |
--- a/pcsx2/MTGS.cpp | |
+++ b/pcsx2/MTGS.cpp | |
@@ -24,6 +24,10 @@ | |
#include "MTVU.h" | |
#include "Elfheader.h" | |
+#ifdef __LIBRETRO__ | |
+extern bool libretro_deinit; | |
+#endif | |
+ | |
using namespace Threading; | |
// ===================================================================================================== | |
@@ -423,6 +427,7 @@ void SysMtgsThread::CloseGS() | |
if( !m_Opened ) return; | |
m_Opened = false; | |
GSclose(); | |
+ log_cb(RETRO_LOG_INFO, "%s\n", __func__); | |
#ifdef __LIBRETRO__ | |
m_thread = {}; | |
#endif | |
@@ -468,6 +473,15 @@ void SysMtgsThread::WaitGS(bool syncRegs, bool weakWait, bool isMTVU) | |
if (isMTVU || m_ReadPos.load(std::memory_order_relaxed) != m_WritePos.load(std::memory_order_relaxed)) { | |
SetEvent(); | |
for(;;) { | |
+#ifdef __LIBRETRO__ | |
+ log_cb(RETRO_LOG_INFO, "%s isrunning=%d isopen=%d\n", __func__, IsRunning(), IsOpen()); | |
+ if (libretro_deinit || !IsRunning()) | |
+ { | |
+ log_cb(RETRO_LOG_INFO, "%s BREAK isrunning=%d\n", __func__, IsRunning()); | |
+ Cancel(); | |
+ break; | |
+ } | |
+#endif | |
if (weakWait) m_mtx_RingBufferBusy2.Wait(); | |
else m_mtx_RingBufferBusy .Wait(); | |
if(!isMTVU && m_ReadPos.load(std::memory_order_relaxed) == m_WritePos.load(std::memory_order_relaxed)) break; | |
diff --git a/pcsx2/MTVU.cpp b/pcsx2/MTVU.cpp | |
index fe28567bf..e6a274d81 100644 | |
--- a/pcsx2/MTVU.cpp | |
+++ b/pcsx2/MTVU.cpp | |
@@ -22,6 +22,10 @@ | |
#include <windows.h> /* for GetExceptionInformation */ | |
#endif | |
+#ifdef __LIBRETRO__ | |
+extern bool libretro_deinit; | |
+#endif | |
+ | |
__aligned16 VU_Thread vu1Thread(CpuVU1, VU1); | |
// Use this when reading read_pos from ee thread | |
@@ -104,6 +108,7 @@ VU_Thread::~VU_Thread() | |
{ | |
try | |
{ | |
+ Reset(); | |
pxThread::Cancel(); | |
} | |
DESTRUCTOR_CATCHALL | |
@@ -139,6 +144,7 @@ void VU_Thread::ExecuteRingBuffer() | |
{ | |
for (;;) | |
{ | |
+ log_cb(RETRO_LOG_INFO, "%s read=%d write=%d\n", __func__, VU_Thread_GetReadPos(), VU_Thread_GetWritePos()); | |
semaEvent.WaitWithoutYield(); | |
ScopedLockBool lock(mtxBusy, isBusy); | |
while (m_ato_read_pos.load(std::memory_order_relaxed) != VU_Thread_GetWritePos()) | |
@@ -212,6 +218,7 @@ __ri void VU_Thread::WaitOnSize(s32 size) | |
{ | |
for (;;) | |
{ | |
+ log_cb(RETRO_LOG_INFO, "%s isrunning=%d\n", __func__, IsRunning()); | |
s32 readPos = VU_Thread_GetReadPos(); | |
if (readPos <= m_write_pos) | |
break; // MTVU is reading in back of write_pos | |
@@ -362,6 +369,16 @@ void VU_Thread::WaitVU() | |
{ | |
for (;;) | |
{ | |
+#ifdef __LIBRETRO__ | |
+ log_cb(RETRO_LOG_INFO, "%s isrunning=%d\n", __func__, IsRunning()); | |
+ if (libretro_deinit || !IsRunning() || semaEvent.Count() > VU_Thread_GetWritePos() - VU_Thread_GetReadPos()) | |
+ { | |
+ log_cb(RETRO_LOG_INFO, "%s BREAK isrunning=%d\n", __func__, IsRunning()); | |
+ //Reset(); | |
+ Cancel(); | |
+ break; | |
+ } | |
+#endif | |
if (VU_Thread_IsDone()) | |
break; | |
KickStart(); | |
diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp | |
index ad5e9c3e0..ac934955a 100644 | |
--- a/pcsx2/System.cpp | |
+++ b/pcsx2/System.cpp | |
@@ -253,17 +253,21 @@ void SysMainMemory::ReserveAll() | |
void SysMainMemory::CommitAll() | |
{ | |
- vtlb_Core_Alloc(); | |
+ log_cb(RETRO_LOG_INFO, "Allocating host memory for virtual systems...\n" ); | |
if (m_ee.IsCommitted() && m_iop.IsCommitted() && m_vu.IsCommitted()) return; | |
+ | |
m_ee.Commit(); | |
m_iop.Commit(); | |
m_vu.Commit(); | |
+ vtlb_Core_Alloc(); | |
} | |
void SysMainMemory::ResetAll() | |
{ | |
- CommitAll(); | |
+ log_cb(RETRO_LOG_INFO, "Resetting host memory for virtual systems...\n" ); | |
+ | |
+ //CommitAll(); | |
m_ee.Reset(); | |
m_iop.Reset(); | |
m_vu.Reset(); | |
@@ -273,23 +277,16 @@ void SysMainMemory::ResetAll() | |
void SysMainMemory::DecommitAll() | |
{ | |
- if (!m_ee.IsCommitted() && !m_iop.IsCommitted() && !m_vu.IsCommitted()) return; | |
+ log_cb(RETRO_LOG_INFO, "%s ee=%d iop=%d vu=%d\n", __func__, m_ee.IsCommitted(), m_iop.IsCommitted(), m_vu.IsCommitted()); | |
+ //if (!m_ee.IsCommitted() && !m_iop.IsCommitted() && !m_vu.IsCommitted()) return; | |
log_cb(RETRO_LOG_INFO, "Decommitting host memory for virtual systems...\n" ); | |
- // On linux, the MTVU isn't empty and the thread still uses the m_ee/m_vu memory | |
- vu1Thread.WaitVU(); | |
- // The EE thread must be stopped here command mustn't be send | |
- // to the ring. Let's call it an extra safety valve :) | |
- vu1Thread.Reset(); | |
- | |
- hwShutdown(); | |
+ //vtlb_Core_Free(); | |
m_ee.Decommit(); | |
m_iop.Decommit(); | |
m_vu.Decommit(); | |
- | |
- vtlb_Core_Free(); | |
} | |
void SysMainMemory::ReleaseAll() | |
@@ -297,13 +294,20 @@ void SysMainMemory::ReleaseAll() | |
DecommitAll(); | |
log_cb(RETRO_LOG_INFO, "Releasing host memory maps for virtual systems...\n" ); | |
+ | |
+ psxRec.Shutdown(); | |
+ recCpu.Shutdown(); | |
+ hwShutdown(); | |
+ | |
// Just to be sure... (calling order could result | |
// in it getting missed during Decommit). | |
vtlb_Core_Free(); | |
- m_ee.Decommit(); | |
- m_iop.Decommit(); | |
- m_vu.Decommit(); | |
+ //vif0Reset(); | |
+ dVifRelease(0); | |
+ | |
+ //vif1Reset(); | |
+ dVifRelease(1); | |
safe_delete(Source_PageFault); | |
} | |
@@ -351,6 +355,7 @@ BaseException* SysCpuProviderPack::GetException_MicroVU1() const { return CpuPro | |
void SysCpuProviderPack::CleanupMess() noexcept | |
{ | |
+ log_cb(RETRO_LOG_INFO, "%s\n", __func__); | |
try | |
{ | |
psxRec.Shutdown(); | |
@@ -364,6 +369,7 @@ void SysCpuProviderPack::CleanupMess() noexcept | |
SysCpuProviderPack::~SysCpuProviderPack() | |
{ | |
+ log_cb(RETRO_LOG_INFO, "%s\n", __func__); | |
CleanupMess(); | |
} | |
diff --git a/pcsx2/System/SysCoreThread.cpp b/pcsx2/System/SysCoreThread.cpp | |
index b52fbb1bd..7e0dbc88c 100644 | |
--- a/pcsx2/System/SysCoreThread.cpp | |
+++ b/pcsx2/System/SysCoreThread.cpp | |
@@ -40,14 +40,18 @@ USBhandler usbHandler; | |
static void modules_close(void) | |
{ | |
+ log_cb(RETRO_LOG_INFO, "%s GSclose isself=%d isrunning=%d isopen=%d\n", __func__, GetMTGS().IsSelf(), GetMTGS().IsRunning(), GetMTGS().IsOpen()); | |
if( GetMTGS().IsSelf() ) | |
{ | |
GSclose(); | |
} | |
else | |
{ | |
- log_cb(RETRO_LOG_INFO, "Closing GS\n"); | |
+ //log_cb(RETRO_LOG_INFO, "Closing GS\n"); | |
+ //GetMTGS().WaitGS(); | |
GetMTGS().Suspend(); | |
+ //GetMTGS().Cancel(); | |
+ //GetMTGS().CloseGS(); | |
} | |
DoCDVDclose(); | |
FWclose(); | |
@@ -100,7 +104,8 @@ static void modules_init(void) | |
static void modules_shutdown(void) | |
{ | |
- GetMTGS().Cancel(); // cancel it for speedier shutdown! | |
+ log_cb(RETRO_LOG_INFO, "%s\n", __func__); | |
+ //GetMTGS().Cancel(); // cancel it for speedier shutdown! | |
GSshutdown(); | |
SPU2shutdown(); | |
PADshutdown(); | |
@@ -339,17 +344,20 @@ void SysCoreThread::OnResumeInThread(bool isSuspended) | |
// Invoked by the pthread_exit or pthread_cancel. | |
void SysCoreThread::OnCleanupInThread() | |
{ | |
+ log_cb(RETRO_LOG_INFO, "%s\n", __func__); | |
m_ExecMode = ExecMode_Closing; | |
m_hasActiveMachine = false; | |
m_resetVirtualMachine = true; | |
R3000A::ioman::reset(); | |
- // FIXME: temporary workaround for deadlock on exit, which actually should be a crash | |
- vu1Thread.WaitVU(); | |
+ vu1Thread.Cancel(); | |
+ | |
modules_close(); | |
modules_shutdown(); | |
+ GetMTGS().Cancel(); | |
+ | |
_mm_setcsr(m_mxcsr_saved.bitmask); | |
_parent::OnCleanupInThread(); | |
diff --git a/plugins/GS/GS.cpp b/plugins/GS/GS.cpp | |
index f28041201..dfce4f7c6 100644 | |
--- a/plugins/GS/GS.cpp | |
+++ b/plugins/GS/GS.cpp | |
@@ -97,6 +97,7 @@ EXPORT_C_(int) GSinit() | |
EXPORT_C GSshutdown() | |
{ | |
+ log_cb(RETRO_LOG_INFO, "%s\n", __func__); | |
delete s_gs; | |
s_gs = nullptr; | |
@@ -105,6 +106,7 @@ EXPORT_C GSshutdown() | |
EXPORT_C GSclose() | |
{ | |
+ log_cb(RETRO_LOG_INFO, "%s\n", __func__); | |
if(s_gs == NULL) return; | |
s_gs->ResetDevice(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment