From ccfaabd1d705f0bb3c07803621935608f7beb4a2 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 19 Jun 2014 17:50:18 +0400 Subject: [PATCH] Defined thread_local for MSVC Updated asmjit project Tried to fix crash on exit Fixed hypothetical issue when pausing already stopped emulator --- .gitignore | 2 ++ Utilities/GNU.h | 6 +++++ Utilities/SMutex.cpp | 9 +------- Utilities/Thread.cpp | 15 ++++++------ asmjit | 2 +- asmjitsrc/asmjit.vcxproj | 11 +++++---- asmjitsrc/asmjit.vcxproj.filters | 11 +++++---- rpcs3/Emu/GS/RSXThread.cpp | 5 ++++ rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp | 2 +- rpcs3/Emu/System.cpp | 28 ++++++++++++++++++++--- 12 files changed, 62 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index cfe1dc5f6e..396f474d54 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,5 @@ rpcs3/git-version.h # Ignore other system generated files bin/dev_hdd0/log.txt +x64/Debug/emucore.lib +x64/Release/emucore.lib diff --git a/Utilities/GNU.h b/Utilities/GNU.h index 32f616a6d2..a3a2ba48e5 100644 --- a/Utilities/GNU.h +++ b/Utilities/GNU.h @@ -1,5 +1,11 @@ #pragma once +#ifdef _WIN32 +#define thread_local __declspec(thread) +#elif __APPLE__ +#define thread_local __thread +#endif + #if defined(__GNUG__) #include #include diff --git a/Utilities/SMutex.cpp b/Utilities/SMutex.cpp index b5ddd548d2..e253a52346 100644 --- a/Utilities/SMutex.cpp +++ b/Utilities/SMutex.cpp @@ -11,14 +11,7 @@ __forceinline void SM_Sleep() Sleep(1); } -#ifdef _WIN32 -__declspec(thread) -#elif __APPLE__ -__thread -#else -thread_local -#endif -size_t g_this_thread_id = 0; +thread_local size_t g_this_thread_id = 0; __forceinline size_t SM_GetCurrentThreadId() { diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index d18728fc5d..dba77485c2 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -3,14 +3,8 @@ #include "Thread.h" -#ifdef _WIN32 -__declspec(thread) -#elif __APPLE__ -__thread -#else -thread_local -#endif -NamedThreadBase* g_tls_this_thread = nullptr; +thread_local NamedThreadBase* g_tls_this_thread = nullptr; +std::atomic g_thread_count = 0; NamedThreadBase* GetCurrentNamedThread() { @@ -56,10 +50,12 @@ void ThreadBase::Start() [this]() { g_tls_this_thread = this; + g_thread_count++; Task(); m_alive = false; + g_thread_count--; }); } @@ -130,6 +126,7 @@ void thread::start(std::function func) { NamedThreadBase info(name); g_tls_this_thread = &info; + g_thread_count++; try { @@ -140,6 +137,8 @@ void thread::start(std::function func) ConLog.Error("Crash :("); //std::terminate(); } + + g_thread_count--; }); } diff --git a/asmjit b/asmjit index b76922fde9..a66efd5460 160000 --- a/asmjit +++ b/asmjit @@ -1 +1 @@ -Subproject commit b76922fde96232030be302b3bdd9673e9bcec568 +Subproject commit a66efd54609aab7dd98e34c069937f34aa7c8f95 diff --git a/asmjitsrc/asmjit.vcxproj b/asmjitsrc/asmjit.vcxproj index 28da0c7bdb..04f30a8e35 100644 --- a/asmjitsrc/asmjit.vcxproj +++ b/asmjitsrc/asmjit.vcxproj @@ -1,4 +1,4 @@ - + @@ -26,12 +26,10 @@ - - - + @@ -42,8 +40,11 @@ - + + + + diff --git a/asmjitsrc/asmjit.vcxproj.filters b/asmjitsrc/asmjit.vcxproj.filters index 3bc6ddf9b2..b82be7b1a7 100644 --- a/asmjitsrc/asmjit.vcxproj.filters +++ b/asmjitsrc/asmjit.vcxproj.filters @@ -1,11 +1,10 @@ - + - @@ -14,18 +13,20 @@ - - - + + + + + diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 096ef0de48..4023a11969 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -1844,6 +1844,11 @@ void RSXThread::Task() while(!TestDestroy()) { + if (Emu.IsStopped()) + { + ConLog.Warning("RSX thread aborted"); + return; + } rCriticalSectionLocker lock(m_cs_main); inc=1; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index d42a0b7ca7..ee394c5254 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -471,7 +471,7 @@ int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) return CELL_GCM_ERROR_FAILURE; } - GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); // could stall on exit + GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); // could freeze on exit u32 current = ctxt->current; u32 end = ctxt->end; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp b/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp index 283072895c..53767cdb94 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_GCM.cpp @@ -13,7 +13,7 @@ extern gcmInfo gcm_info; int cellGcmCallback(u32 context_addr, u32 count) { - GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); // could stall on exit + GSLockCurrent gslock(GS_LOCK_WAIT_FLUSH); // could freeze on exit CellGcmContextData& ctx = (CellGcmContextData&)Memory[context_addr]; CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr]; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp index c383dae656..9e31b63c62 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_PPU_Thread.cpp @@ -83,7 +83,7 @@ void sys_ppu_thread_get_join_state(u32 isjoinable_addr) int sys_ppu_thread_set_priority(u32 thread_id, int prio) { - sysPrxForUser->Warning("sys_ppu_thread_set_priority(thread_id=%d, prio=%d)", thread_id, prio); + sysPrxForUser->Log("sys_ppu_thread_set_priority(thread_id=%d, prio=%d)", thread_id, prio); CPUThread* thr = Emu.GetCPU().GetThread(thread_id); if(!thr) return CELL_ESRCH; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index f07840c167..e599ceb217 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -21,6 +21,7 @@ using namespace PPU_instr; static const std::string& BreakPointsDBName = "BreakPoints.dat"; static const u16 bpdb_version = 0x1000; +extern std::atomic g_thread_count; ModuleInitializer::ModuleInitializer() { @@ -345,8 +346,10 @@ void Emulator::Pause() //ConLog.Write("pause..."); SendDbgCommand(DID_PAUSE_EMU); - m_status = Paused; - SendDbgCommand(DID_PAUSED_EMU); + if (InterlockedCompareExchange((volatile unsigned long*)&m_status, Paused, Running) == Running) + { + SendDbgCommand(DID_PAUSED_EMU); + } } void Emulator::Resume() @@ -370,8 +373,27 @@ void Emulator::Stop() SendDbgCommand(DID_STOP_EMU); m_status = Stopped; + u32 uncounted = 0 + (u32)(bool)m_dbg_console; + u32 counter = 0; + while (true) + { + if (g_thread_count <= uncounted) + { + ConLog.Write("All threads stopped..."); + break; + } + Sleep(1); + if (counter++ > 3000) + { + ConLog.Error("%d threads not stopped (timeout)", (u32)(g_thread_count - uncounted)); + break; + } + } + m_rsx_callback = 0; + // TODO: check finalization order + SavePoints(BreakPointsDBName); m_break_points.clear(); m_marked_points.clear(); @@ -388,7 +410,7 @@ void Emulator::Stop() GetKeyboardManager().Close(); GetMouseManager().Close(); GetCallbackManager().Clear(); - //not all modules unload cleanly, so we're not unloading them for now + // TODO: not all modules unload cleanly, so we're not unloading them for now //GetModuleManager().UnloadModules(); CurGameInfo.Reset();