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:
parent
eec7cba0af
commit
3c9b5bbf7b
|
@ -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()
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue