prx_mem memory leak fixed

CPUThread::ExecAsCallback (experimental)
This commit is contained in:
Nekotekina 2014-03-04 23:18:17 +04:00
parent b32a8e2e28
commit 384536ba4f
11 changed files with 133 additions and 39 deletions

View file

@ -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);
}
};

View file

@ -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;
}

View file

@ -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;

View file

@ -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];

View file

@ -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);

View file

@ -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)

View file

@ -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;
}

View file

@ -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)
{
}
};

View file

@ -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)

View file

@ -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)

View file

@ -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;