mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
prx_mem memory leak fixed
CPUThread::ExecAsCallback (experimental)
This commit is contained in:
parent
b32a8e2e28
commit
384536ba4f
11 changed files with 133 additions and 39 deletions
|
@ -145,15 +145,19 @@ public:
|
|||
{
|
||||
if (!tid)
|
||||
{
|
||||
ConLog.Error("SMutexLockerBase: thread id == 0");
|
||||
Emu.Pause();
|
||||
if (!Emu.IsStopped())
|
||||
{
|
||||
ConLog.Error("SMutexLockerBase: thread id == 0");
|
||||
Emu.Pause();
|
||||
}
|
||||
return;
|
||||
}
|
||||
sm.lock(tid);
|
||||
}
|
||||
|
||||
~SMutexLockerBase()
|
||||
{
|
||||
sm.unlock(tid);
|
||||
if (tid) sm.unlock(tid);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -360,3 +360,44 @@ void CPUThread::Task()
|
|||
|
||||
if (Ini.HLELogging.GetValue()) ConLog.Write("%s leave", CPUThread::GetFName().wx_str());
|
||||
}
|
||||
|
||||
int CPUThread::ExecAsCallback(u64 pc, bool wait, u64 a1, u64 a2, u64 a3, u64 a4) // not multithread-safe
|
||||
{
|
||||
while (m_alive)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("ExecAsCallback() aborted");
|
||||
return CELL_ECANCELED; // doesn't mean anything
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
Stop();
|
||||
Reset();
|
||||
|
||||
SetEntry(pc);
|
||||
SetPrio(1001);
|
||||
SetStackSize(0x10000);
|
||||
SetExitStatus(CELL_OK);
|
||||
|
||||
SetArg(0, a1);
|
||||
SetArg(1, a2);
|
||||
SetArg(2, a3);
|
||||
SetArg(3, a4);
|
||||
Run();
|
||||
|
||||
Exec();
|
||||
|
||||
while (wait && m_alive)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("ExecAsCallback() aborted");
|
||||
return CELL_EABORT; // doesn't mean anything
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
return wait * m_exit_status;
|
||||
}
|
|
@ -234,6 +234,8 @@ public:
|
|||
return pc + 4;
|
||||
}
|
||||
|
||||
int ExecAsCallback(u64 pc, bool wait, u64 a1 = 0, u64 a2 = 0, u64 a3 = 0, u64 a4 = 0);
|
||||
|
||||
protected:
|
||||
virtual void DoReset()=0;
|
||||
virtual void DoRun()=0;
|
||||
|
|
|
@ -118,14 +118,11 @@ void PPUThread::InitRegs()
|
|||
GPR[6] = m_args[3];
|
||||
}
|
||||
|
||||
u32 prx_mem = Memory.PRXMem.AllocAlign(0x10000);
|
||||
Memory.Write64(prx_mem, 0xDEADBEEFABADCAFE);
|
||||
|
||||
GPR[0] = pc;
|
||||
GPR[8] = entry;
|
||||
GPR[11] = 0x80;
|
||||
GPR[12] = Emu.GetMallocPageSize();
|
||||
GPR[13] = prx_mem + 0x7060;
|
||||
GPR[13] = Memory.PRXMem.GetStartAddr() + 0x7060;
|
||||
GPR[28] = GPR[4];
|
||||
GPR[29] = GPR[3];
|
||||
GPR[31] = GPR[5];
|
||||
|
|
|
@ -47,6 +47,8 @@ u32 adecOpen(AudioDecoder* data)
|
|||
{
|
||||
AudioDecoder& adec = *data;
|
||||
|
||||
adec.adecCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
u32 adec_id = cellAdec.GetNewId(data);
|
||||
|
||||
adec.id = adec_id;
|
||||
|
@ -70,11 +72,11 @@ u32 adecOpen(AudioDecoder* data)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (adec.frames.GetCount() >= 50)
|
||||
/*if (adec.frames.GetCount() >= 50)
|
||||
{
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (!adec.job.Pop(task))
|
||||
{
|
||||
|
@ -100,10 +102,11 @@ u32 adecOpen(AudioDecoder* data)
|
|||
// TODO: finalize
|
||||
ConLog.Warning("adecEndSeq:");
|
||||
|
||||
Callback cb;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(adec.cbFunc);
|
||||
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);
|
||||
cb.Branch(true); // ???
|
||||
cb.Branch(true); // ???*/
|
||||
adec.adecCb->ExecAsCallback(adec.cbFunc, true, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg);
|
||||
|
||||
avcodec_close(adec.ctx);
|
||||
avformat_close_input(&adec.fmt);
|
||||
|
@ -214,14 +217,15 @@ u32 adecOpen(AudioDecoder* data)
|
|||
frame.auAddr = task.au.addr;
|
||||
frame.auSize = task.au.size;
|
||||
frame.userdata = task.au.userdata;
|
||||
frame.size = 2048;
|
||||
frame.size = 4096;
|
||||
frame.data = nullptr;
|
||||
adec.frames.Push(frame);
|
||||
|
||||
Callback cb;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(adec.cbFunc);
|
||||
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
||||
cb.Branch(false);
|
||||
cb.Branch(false);*/
|
||||
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -273,17 +277,19 @@ u32 adecOpen(AudioDecoder* data)
|
|||
adec.frames.Push(frame);
|
||||
frame.data = nullptr; // to prevent destruction
|
||||
|
||||
Callback cb;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(adec.cbFunc);
|
||||
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
||||
cb.Branch(false);
|
||||
cb.Branch(false);*/
|
||||
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_PCMOUT, CELL_OK, adec.cbArg);
|
||||
}
|
||||
}
|
||||
|
||||
Callback cb;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(adec.cbFunc);
|
||||
cb.Handle(adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg);
|
||||
cb.Branch(false);
|
||||
cb.Branch(false);*/
|
||||
adec.adecCb->ExecAsCallback(adec.cbFunc, false, adec.id, CELL_ADEC_MSG_TYPE_AUDONE, task.au.auInfo_addr, adec.cbArg);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -408,6 +414,7 @@ int cellAdecClose(u32 handle)
|
|||
Sleep(1);
|
||||
}
|
||||
|
||||
if (adec->adecCb) Emu.GetCPU().RemoveThread(adec->adecCb->GetId());
|
||||
Emu.GetIdManager().RemoveID(handle);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -506,6 +513,10 @@ int cellAdecGetPcm(u32 handle, u32 outBuffer_addr)
|
|||
// copy data
|
||||
if (!af.data) // fake: empty data
|
||||
{
|
||||
u8* buf = (u8*)malloc(4096);
|
||||
memset(buf, 0, 4096);
|
||||
Memory.CopyFromReal(outBuffer_addr, buf, 4096);
|
||||
free(buf);
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
@ -546,7 +557,9 @@ int cellAdecGetPcmItem(u32 handle, mem32_t pcmItem_ptr)
|
|||
|
||||
adec->memBias += 512;
|
||||
if (adec->memBias + 512 > adec->memSize)
|
||||
{
|
||||
adec->memBias = 0;
|
||||
}
|
||||
|
||||
pcm->pcmHandle = 0; // ???
|
||||
pcm->pcmAttr.bsiInfo_addr = pcm.GetAddr() + sizeof(CellAdecPcmItem);
|
||||
|
|
|
@ -1064,6 +1064,8 @@ public:
|
|||
const u32 cbArg;
|
||||
u32 memBias;
|
||||
|
||||
CPUThread* adecCb;
|
||||
|
||||
AudioDecoder(AudioCodecType type, u32 addr, u32 size, u32 func, u32 arg)
|
||||
: type(type)
|
||||
, memAddr(addr)
|
||||
|
@ -1071,6 +1073,7 @@ public:
|
|||
, memBias(0)
|
||||
, cbFunc(func)
|
||||
, cbArg(arg)
|
||||
, adecCb(nullptr)
|
||||
, is_running(false)
|
||||
, is_finished(false)
|
||||
, just_started(false)
|
||||
|
|
|
@ -20,7 +20,7 @@ void dmuxQueryEsAttr(u32 info_addr /* may be 0 */, const mem_ptr_t<CellCodecEsFi
|
|||
if (esFilterId->filterIdMajor >= 0xe0)
|
||||
attr->memSize = 0x2000000; // 0x45fa49 from ps3
|
||||
else
|
||||
attr->memSize = 0x400000; // 0x73d9 from ps3
|
||||
attr->memSize = 0x100000; // 0x73d9 from ps3
|
||||
|
||||
cellDmux.Warning("*** filter(0x%x, 0x%x, 0x%x, 0x%x)", (u32)esFilterId->filterIdMajor, (u32)esFilterId->filterIdMinor,
|
||||
(u32)esFilterId->supplementalInfo1, (u32)esFilterId->supplementalInfo2);
|
||||
|
@ -30,6 +30,8 @@ u32 dmuxOpen(Demuxer* data)
|
|||
{
|
||||
Demuxer& dmux = *data;
|
||||
|
||||
dmux.dmuxCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
u32 dmux_id = cellDmux.GetNewId(data);
|
||||
|
||||
dmux.id = dmux_id;
|
||||
|
@ -138,10 +140,11 @@ u32 dmuxOpen(Demuxer* data)
|
|||
mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
|
||||
esMsg->supplementalInfo = stream.userdata;
|
||||
Callback cb;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(es.cbFunc);
|
||||
cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
|
||||
cb.Branch(false);
|
||||
cb.Branch(false);*/
|
||||
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -184,10 +187,11 @@ u32 dmuxOpen(Demuxer* data)
|
|||
mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
|
||||
esMsg->supplementalInfo = stream.userdata;
|
||||
Callback cb;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(es.cbFunc);
|
||||
cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
|
||||
cb.Branch(false);
|
||||
cb.Branch(false);*/
|
||||
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
|
||||
}
|
||||
|
||||
if (pes.new_au)
|
||||
|
@ -292,10 +296,12 @@ task:
|
|||
mem_ptr_t<CellDmuxMsg> dmuxMsg(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
dmuxMsg->msgType = CELL_DMUX_MSG_TYPE_DEMUX_DONE;
|
||||
dmuxMsg->supplementalInfo = stream.userdata;
|
||||
Callback cb;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(dmux.cbFunc);
|
||||
cb.Handle(dmux.id, dmuxMsg.GetAddr(), dmux.cbArg);
|
||||
cb.Branch(task.type == dmuxResetStreamAndWaitDone);
|
||||
cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/
|
||||
dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, task.type == dmuxResetStreamAndWaitDone,
|
||||
dmux.id, dmuxMsg.GetAddr(), dmux.cbArg);
|
||||
dmux.is_running = false;
|
||||
}
|
||||
break;
|
||||
|
@ -370,20 +376,22 @@ task:
|
|||
mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND;
|
||||
esMsg->supplementalInfo = stream.userdata;
|
||||
Callback cb;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(es.cbFunc);
|
||||
cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
|
||||
cb.Branch(false);
|
||||
cb.Branch(false);*/
|
||||
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
|
||||
}
|
||||
|
||||
// callback
|
||||
mem_ptr_t<CellDmuxEsMsg> esMsg(a128(dmux.memAddr) + (cb_add ^= 16));
|
||||
esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_FLUSH_DONE;
|
||||
esMsg->supplementalInfo = stream.userdata;
|
||||
Callback cb;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(es.cbFunc);
|
||||
cb.Handle(dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
|
||||
cb.Branch(false);
|
||||
cb.Branch(false);*/
|
||||
dmux.dmuxCb->ExecAsCallback(es.cbFunc, false, dmux.id, es.id, esMsg.GetAddr(), es.cbArg);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -549,6 +557,7 @@ int cellDmuxClose(u32 demuxerHandle)
|
|||
Sleep(1);
|
||||
}
|
||||
|
||||
if (dmux->dmuxCb) Emu.GetCPU().RemoveThread(dmux->dmuxCb->GetId());
|
||||
Emu.GetIdManager().RemoveID(demuxerHandle);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
|
|
@ -470,6 +470,7 @@ public:
|
|||
volatile bool is_finished;
|
||||
volatile bool is_running;
|
||||
|
||||
CPUThread* dmuxCb;
|
||||
|
||||
Demuxer(u32 addr, u32 size, u32 func, u32 arg)
|
||||
: is_finished(false)
|
||||
|
@ -478,6 +479,7 @@ public:
|
|||
, memSize(size)
|
||||
, cbFunc(func)
|
||||
, cbArg(arg)
|
||||
, dmuxCb(nullptr)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -55,10 +55,11 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
|
|||
buf_size -= vdec.reader.size;
|
||||
res += vdec.reader.size;
|
||||
|
||||
Callback cb;
|
||||
/*Callback cb;
|
||||
cb.SetAddr(vdec.cbFunc);
|
||||
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
|
||||
cb.Branch(false);
|
||||
cb.Branch(false);*/
|
||||
vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
|
||||
|
||||
vdec.job.Pop(vdec.task);
|
||||
|
||||
|
@ -73,6 +74,7 @@ int vdecRead(void* opaque, u8* buf, int buf_size)
|
|||
ConLog.Error("vdecRead(): sequence error (task %d)", vdec.job.Peek().type);
|
||||
return 0;
|
||||
}
|
||||
//buf_size = vdec.reader.size;
|
||||
}
|
||||
|
||||
if (!buf_size)
|
||||
|
@ -115,6 +117,8 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
{
|
||||
VideoDecoder& vdec = *data;
|
||||
|
||||
vdec.vdecCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU);
|
||||
|
||||
u32 vdec_id = cellVdec.GetNewId(data);
|
||||
|
||||
vdec.id = vdec_id;
|
||||
|
@ -168,10 +172,11 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
// TODO: finalize
|
||||
ConLog.Warning("vdecEndSeq:");
|
||||
|
||||
Callback cb;
|
||||
vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg);
|
||||
/*Callback cb;
|
||||
cb.SetAddr(vdec.cbFunc);
|
||||
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg);
|
||||
cb.Branch(true); // ???
|
||||
cb.Branch(true); // ???*/
|
||||
|
||||
avcodec_close(vdec.ctx);
|
||||
avformat_close_input(&vdec.fmt);
|
||||
|
@ -268,6 +273,8 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
Emu.Pause();
|
||||
break;
|
||||
}
|
||||
//vdec.ctx->flags |= CODEC_FLAG_TRUNCATED;
|
||||
//vdec.ctx->flags2 |= CODEC_FLAG2_CHUNKS;
|
||||
vdec.just_started = false;
|
||||
}
|
||||
|
||||
|
@ -275,9 +282,15 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
|
||||
while (true)
|
||||
{
|
||||
if (Emu.IsStopped())
|
||||
{
|
||||
ConLog.Warning("vdecDecodeAu aborted");
|
||||
return;
|
||||
}
|
||||
last_frame = av_read_frame(vdec.fmt, &au) < 0;
|
||||
if (last_frame)
|
||||
{
|
||||
//break;
|
||||
av_free(au.data);
|
||||
au.data = NULL;
|
||||
au.size = 0;
|
||||
|
@ -329,20 +342,22 @@ u32 vdecOpen(VideoDecoder* data)
|
|||
frame.dts = vdec.last_dts; vdec.last_dts += 3003; // + duration???
|
||||
frame.pts = vdec.last_pts; vdec.last_pts += 3003;
|
||||
frame.userdata = task.userData;
|
||||
vdec.frames.Push(frame);
|
||||
vdec.frames.Push(frame); // !!!!!!!!
|
||||
frame.data = nullptr; // to prevent destruction
|
||||
|
||||
Callback cb;
|
||||
vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg);
|
||||
/*Callback cb;
|
||||
cb.SetAddr(vdec.cbFunc);
|
||||
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_PICOUT, CELL_OK, vdec.cbArg);
|
||||
cb.Branch(false);
|
||||
cb.Branch(false);*/
|
||||
}
|
||||
}
|
||||
|
||||
Callback cb;
|
||||
vdec.vdecCb->ExecAsCallback(vdec.cbFunc, false, vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
|
||||
/*Callback cb;
|
||||
cb.SetAddr(vdec.cbFunc);
|
||||
cb.Handle(vdec.id, CELL_VDEC_MSG_TYPE_AUDONE, CELL_OK, vdec.cbArg);
|
||||
cb.Branch(false);
|
||||
cb.Branch(false);*/
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -459,6 +474,7 @@ int cellVdecClose(u32 handle)
|
|||
Sleep(1);
|
||||
}
|
||||
|
||||
if (vdec->vdecCb) Emu.GetCPU().RemoveThread(vdec->vdecCb->GetId());
|
||||
Emu.GetIdManager().RemoveID(handle);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -638,7 +654,9 @@ int cellVdecGetPicItem(u32 handle, mem32_t picItem_ptr)
|
|||
|
||||
vdec->memBias += 512;
|
||||
if (vdec->memBias + 512 > vdec->memSize)
|
||||
{
|
||||
vdec->memBias = 0;
|
||||
}
|
||||
|
||||
info->codecType = vdec->type;
|
||||
info->startAddr = 0x00000123; // invalid value (no address for picture)
|
||||
|
|
|
@ -718,9 +718,11 @@ public:
|
|||
const u32 cbArg;
|
||||
u32 memBias;
|
||||
|
||||
VdecTask task; // reference to current task variable
|
||||
VdecTask task; // current task variable
|
||||
u64 last_pts, last_dts;
|
||||
|
||||
CPUThread* vdecCb;
|
||||
|
||||
VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, u32 func, u32 arg)
|
||||
: type(type)
|
||||
, profile(profile)
|
||||
|
@ -733,6 +735,7 @@ public:
|
|||
, is_running(false)
|
||||
, just_started(false)
|
||||
, ctx(nullptr)
|
||||
, vdecCb(nullptr)
|
||||
{
|
||||
AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_H264);
|
||||
if (!codec)
|
||||
|
|
|
@ -267,6 +267,8 @@ void Emulator::Load()
|
|||
ppu_thr_exit_data += ADDI(11, 0, 41);
|
||||
ppu_thr_exit_data += SC(2);
|
||||
ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0);
|
||||
|
||||
Memory.Write64(Memory.PRXMem.AllocAlign(0x10000), 0xDEADBEEFABADCAFE);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue