From bae8c6ed9cc31c94bc1dd3b2cd68bfa05e17468d Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 30 Jul 2010 09:24:23 +0000 Subject: [PATCH] Fixed the crash that occurred while loading and saving states. This change freezes the system while a save state is being made or loaded, ensuring that the sub-systems (e.g. CPU and GPU) is in a consistent state when the save-state is created. Removed the clearing of the JIT cache as invalidated memory would sometimes be jumped to from the block descriptors, causing the crash. Removed the saving of the old JIT unlimited icache from the state as this now serves only as transient data to track what has been compiled in the JIT (and it took up a lot of space). The icache is now saved inside the PPCState. Fixes issue 2964. (I hope) HAPPY 6000th!!! git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6000 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/State.cpp | 44 ++++++++++++++++------------------ 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/Source/Core/Core/Src/State.cpp b/Source/Core/Core/Src/State.cpp index b4ae93bde8..56fdc2f62d 100644 --- a/Source/Core/Core/Src/State.cpp +++ b/Source/Core/Core/Src/State.cpp @@ -71,7 +71,7 @@ static Common::Thread *saveThread = NULL; // Don't forget to increase this after doing changes on the savestate system -#define STATE_VERSION 2 +#define STATE_VERSION 3 void DoState(PointerWrap &p) @@ -93,16 +93,6 @@ void DoState(PointerWrap &p) PowerPC::DoState(p); HW::DoState(p); CoreTiming::DoState(p); - - // TODO: it's a GIGANTIC waste of time and space to savestate the following - // (adds 128MB of mostly-empty cache data to every savestate). - // it seems to be unnecessary as far as I can tell, - // but I can't prove it is yet so I'll leave it here for now... -#ifdef JIT_UNLIMITED_ICACHE - p.DoVoid(jit->GetBlockCache()->GetICache(), JIT_ICACHE_SIZE); - p.DoVoid(jit->GetBlockCache()->GetICacheEx(), JIT_ICACHEEX_SIZE); - p.DoVoid(jit->GetBlockCache()->GetICacheVMEM(), JIT_ICACHE_SIZE); -#endif } void LoadBufferStateCallback(u64 userdata, int cyclesLate) @@ -112,8 +102,6 @@ void LoadBufferStateCallback(u64 userdata, int cyclesLate) return; } - jit->ClearCache(); - u8 *ptr = *cur_buffer; PointerWrap p(&ptr, PointerWrap::MODE_READ); DoState(p); @@ -129,8 +117,6 @@ void SaveBufferStateCallback(u64 userdata, int cyclesLate) return; } - jit->ClearCache(); - u8 *ptr = NULL; PointerWrap p(&ptr, PointerWrap::MODE_MEASURE); @@ -163,8 +149,6 @@ void VerifyBufferStateCallback(u64 userdata, int cyclesLate) return; } - jit->ClearCache(); - u8 *ptr = *cur_buffer; PointerWrap p(&ptr, PointerWrap::MODE_VERIFY); DoState(p); @@ -248,9 +232,13 @@ THREAD_RETURN CompressAndDumpState(void *pArgs) void SaveStateCallback(u64 userdata, int cyclesLate) { - State_Flush(); + // Stop the clock while we save the state + PowerPC::Pause(); - jit->ClearCache(); + // Wait for the other threaded sub-systems to stop too + Sleep(100); + + State_Flush(); // Measure the size of the buffer. u8 *ptr = 0; @@ -271,12 +259,21 @@ void SaveStateCallback(u64 userdata, int cyclesLate) Core::DisplayMessage("Saving State...", 1000); saveThread = new Common::Thread(CompressAndDumpState, saveData); + + // Resume the clock + PowerPC::Start(); } void LoadStateCallback(u64 userdata, int cyclesLate) { bool bCompressedState; + // Stop the clock while we load the state + PowerPC::Pause(); + + // Wait for the other threaded sub-systems to stop too + Sleep(100); + State_Flush(); // Save temp buffer for undo load state @@ -362,8 +359,6 @@ void LoadStateCallback(u64 userdata, int cyclesLate) fclose(f); - jit->ClearCache(); - u8 *ptr = buffer; PointerWrap p(&ptr, PointerWrap::MODE_READ); DoState(p); @@ -374,6 +369,11 @@ void LoadStateCallback(u64 userdata, int cyclesLate) Core::DisplayMessage("Unable to Load : Can't load state from other revisions !", 4000); delete[] buffer; + + state_op_in_progress = false; + + // Resume the clock + PowerPC::Start(); } void VerifyStateCallback(u64 userdata, int cyclesLate) @@ -456,8 +456,6 @@ void VerifyStateCallback(u64 userdata, int cyclesLate) fclose(f); - jit->ClearCache(); - u8 *ptr = buffer; PointerWrap p(&ptr, PointerWrap::MODE_VERIFY); DoState(p);