Fixed the load-state memory leak, also fixed various other savestate issues. Found (probably) the cause of load-state crashing Dolphin: BPWrites. Tried to put a CriticalSection around BPWritten but it only causes Dolphin to hang when loading a state. Can someone find why it hangs?

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3873 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
XTra.KrazzY 2009-07-22 22:50:52 +00:00
parent eec7cba0af
commit 3c9b5bbf7b
3 changed files with 62 additions and 43 deletions

View File

@ -84,6 +84,8 @@ void DoState(PointerWrap &p)
pm.GetVideo()->DoState(p.GetPPtr(), p.GetMode()); pm.GetVideo()->DoState(p.GetPPtr(), p.GetMode());
pm.GetDSP()->DoState(p.GetPPtr(), p.GetMode()); pm.GetDSP()->DoState(p.GetPPtr(), p.GetMode());
pm.GetPad(0)->DoState(p.GetPPtr(), p.GetMode()); pm.GetPad(0)->DoState(p.GetPPtr(), p.GetMode());
if(Core::g_CoreStartupParameter.bWii)
pm.GetWiimote(0)->DoState(p.GetPPtr(), p.GetMode());
PowerPC::DoState(p); PowerPC::DoState(p);
HW::DoState(p); HW::DoState(p);
CoreTiming::DoState(p); CoreTiming::DoState(p);
@ -124,6 +126,9 @@ void SaveBufferStateCallback(u64 userdata, int cyclesLate)
DoState(p); DoState(p);
sz = (size_t)ptr; sz = (size_t)ptr;
if(*cur_buffer)
delete[] (*cur_buffer);
*cur_buffer = new u8[sz]; *cur_buffer = new u8[sz];
ptr = *cur_buffer; ptr = *cur_buffer;
p.SetMode(PointerWrap::MODE_WRITE); p.SetMode(PointerWrap::MODE_WRITE);
@ -155,6 +160,7 @@ THREAD_RETURN CompressAndDumpState(void *pArgs)
FILE *f = fopen(filename.c_str(), "wb"); FILE *f = fopen(filename.c_str(), "wb");
if(f == NULL) { if(f == NULL) {
Core::DisplayMessage("Could not save state", 2000); Core::DisplayMessage("Could not save state", 2000);
delete [] buffer;
return 0; return 0;
} }
@ -165,30 +171,27 @@ THREAD_RETURN CompressAndDumpState(void *pArgs)
fwrite(&header, sizeof(state_header), 1, f); fwrite(&header, sizeof(state_header), 1, f);
if (bCompressed) { if (bCompressed) {
if (lzo_init() != LZO_E_OK) lzo_uint cur_len;
PanicAlert("Internal LZO Error - lzo_init() failed"); lzo_uint i = 0;
else {
lzo_uint cur_len;
lzo_uint i = 0;
for(;;) { for(;;) {
if((i + IN_LEN) >= sz) if((i + IN_LEN) >= sz)
cur_len = sz - i; cur_len = sz - i;
else else
cur_len = IN_LEN; cur_len = IN_LEN;
if(lzo1x_1_compress((buffer + i), cur_len, out, &out_len, wrkmem) != LZO_E_OK) if(lzo1x_1_compress((buffer + i), cur_len, out, &out_len, wrkmem) != LZO_E_OK)
PanicAlert("Internal LZO Error - compression failed"); PanicAlert("Internal LZO Error - compression failed");
// The size of the data to write is 'out_len' // The size of the data to write is 'out_len'
fwrite(&out_len, sizeof(int), 1, f); fwrite(&out_len, sizeof(int), 1, f);
fwrite(out, out_len, 1, f); fwrite(out, out_len, 1, f);
if(cur_len != IN_LEN) if(cur_len != IN_LEN)
break; break;
i += cur_len; i += cur_len;
}
} }
} else } else
fwrite(buffer, sz, 1, f); fwrite(buffer, sz, 1, f);
@ -278,28 +281,31 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
if (bCompressedState) { if (bCompressedState) {
Core::DisplayMessage("Decompressing State...", 500); Core::DisplayMessage("Decompressing State...", 500);
if (lzo_init() != LZO_E_OK) lzo_uint i = 0;
PanicAlert("Internal LZO Error - lzo_init() failed"); buffer = new u8[sz];
else { if(!buffer) {
lzo_uint i = 0; PanicAlert("Error allocating buffer");
buffer = new u8[sz]; return;
}
for (;;) {
if (fread(&cur_len, 1, sizeof(int), f) == 0)
break;
fread(out, 1, cur_len, f);
int res = lzo1x_decompress(out, cur_len, (buffer + i), &new_len, NULL);
if(res != LZO_E_OK) {
PanicAlert("Internal LZO Error - decompression failed (%d)\n"
"Try loading the state again", res);
fclose(f);
return;
}
// The size of the data to read to our buffer is 'new_len' for (;;) {
i += new_len; if (fread(&cur_len, 1, sizeof(int), f) == 0)
break;
fread(out, 1, cur_len, f);
int res = lzo1x_decompress(out, cur_len, (buffer + i), &new_len, NULL);
if(res != LZO_E_OK) {
PanicAlert("Internal LZO Error - decompression failed (%d) (%d, %d) \n"
"Try loading the state again", res, i, new_len);
fclose(f);
delete[] buffer;
return;
} }
// The size of the data to read to our buffer is 'new_len'
i += new_len;
} }
} else { } else {
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
@ -331,6 +337,9 @@ void State_Init()
ev_Save = CoreTiming::RegisterEvent("SaveState", &SaveStateCallback); ev_Save = CoreTiming::RegisterEvent("SaveState", &SaveStateCallback);
ev_BufferLoad = CoreTiming::RegisterEvent("LoadBufferState", &LoadBufferStateCallback); ev_BufferLoad = CoreTiming::RegisterEvent("LoadBufferState", &LoadBufferStateCallback);
ev_BufferSave = CoreTiming::RegisterEvent("SaveBufferState", &SaveBufferStateCallback); ev_BufferSave = CoreTiming::RegisterEvent("SaveBufferState", &SaveBufferStateCallback);
if (lzo_init() != LZO_E_OK)
PanicAlert("Internal LZO Error - lzo_init() failed");
} }
void State_Shutdown() void State_Shutdown()

View File

@ -27,15 +27,20 @@
#include "OpcodeDecoding.h" #include "OpcodeDecoding.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "VertexShaderManager.h" #include "VertexShaderManager.h"
#include "Thread.h"
using namespace BPFunctions; using namespace BPFunctions;
// FIXME: Hangs load-state, but should fix graphic-heavy games state loading
//Common::CriticalSection s_bpCritical;
void BPInit() void BPInit()
{ {
memset(&bpmem, 0, sizeof(bpmem)); memset(&bpmem, 0, sizeof(bpmem));
bpmem.bpMask = 0xFFFFFF; bpmem.bpMask = 0xFFFFFF;
} }
// ---------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------
// Write to the Bypass Memory (Bypass Raster State Registers) // Write to the Bypass Memory (Bypass Raster State Registers)
/* ------------------ /* ------------------
@ -73,6 +78,9 @@ void BPWritten(const Bypass& bp)
//default: break; //default: break;
//} //}
// FIXME: Hangs load-state, but should fix graphic-heavy games state loading
//s_bpCritical.Enter();
FlushPipeline(); FlushPipeline();
((u32*)&bpmem)[bp.address] = bp.newvalue; ((u32*)&bpmem)[bp.address] = bp.newvalue;
@ -605,10 +613,11 @@ void BPWritten(const Bypass& bp)
default: default:
WARN_LOG(VIDEO, "Unknown BP opcode: address = 0x%08x value = 0x%08x", bp.address, bp.newvalue); WARN_LOG(VIDEO, "Unknown BP opcode: address = 0x%08x value = 0x%08x", bp.address, bp.newvalue);
break; break;
} }
}
} }
// FIXME: Hangs load-state, but should fix graphic-heavy games state loading
//s_bpCritical.Leave();
}
} }

View File

@ -53,7 +53,8 @@ u16 CMailHandler::ReadDSPMailboxLow()
if (!m_Mails.empty()) if (!m_Mails.empty())
{ {
u16 result = m_Mails.front() & 0xFFFF; u16 result = m_Mails.front() & 0xFFFF;
m_Mails.pop();
m_Mails.pop();
Update(); Update();