sys_event improved, some unnamed functions named

This commit is contained in:
Nekotekina 2015-07-20 22:41:19 +03:00
parent 6019e02457
commit 0aefaec46e
6 changed files with 107 additions and 54 deletions

View file

@ -1318,7 +1318,14 @@ void SPUThread::stop_and_signal(u32 code)
throw EXCEPTION("Unexpected SPU Thread Group state (%d)", group->state);
}
if (queue->events.empty() || !queue->sq.empty())
if (queue->events.size())
{
auto& event = queue->events.front();
ch_in_mbox.set_values(4, CELL_OK, static_cast<u32>(std::get<1>(event)), static_cast<u32>(std::get<2>(event)), static_cast<u32>(std::get<3>(event)));
queue->events.pop_front();
}
else
{
// add waiter; protocol is ignored in current implementation
sleep_queue_entry_t waiter(*this, queue->sq);
@ -1332,23 +1339,8 @@ void SPUThread::stop_and_signal(u32 code)
cv.wait(lv2_lock);
}
}
if (queue->events.empty())
{
if (Emu.GetIdManager().check_id<lv2_event_queue_t>(queue->id))
{
throw EXCEPTION("Unexpected");
}
ch_in_mbox.set_values(1, CELL_ECANCELED);
}
else
{
auto& event = queue->events.front();
ch_in_mbox.set_values(4, CELL_OK, static_cast<u32>(std::get<1>(event)), static_cast<u32>(std::get<2>(event)), static_cast<u32>(std::get<3>(event)));
queue->events.pop_front();
// event data must be set by push()
}
// restore thread group status

View file

@ -546,8 +546,10 @@ s32 cellAdecOpenEx(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResourceEx> res,
return CELL_OK;
}
s32 _nid_df982d2c(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResourceEx> res, vm::ptr<CellAdecCb> cb, vm::ptr<u32> handle)
s32 cellAdecOpenExt(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResourceEx> res, vm::ptr<CellAdecCb> cb, vm::ptr<u32> handle)
{
cellAdec.Warning("cellAdecOpenExt(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle);
return cellAdecOpenEx(type, res, cb, handle);
}
@ -868,7 +870,7 @@ Module cellAdec("cellAdec", []()
REG_FUNC(cellAdec, cellAdecQueryAttr);
REG_FUNC(cellAdec, cellAdecOpen);
REG_FUNC(cellAdec, cellAdecOpenEx);
REG_UNNAMED(cellAdec, df982d2c);
REG_FUNC(cellAdec, cellAdecOpenExt); // 0xdf982d2c
REG_FUNC(cellAdec, cellAdecClose);
REG_FUNC(cellAdec, cellAdecStartSeq);
REG_FUNC(cellAdec, cellAdecEndSeq);

View file

@ -826,8 +826,10 @@ s32 cellDmuxOpenEx(vm::cptr<CellDmuxType> type, vm::cptr<CellDmuxResourceEx> res
return CELL_OK;
}
s32 _nid_e075fabc(vm::cptr<CellDmuxType> type, vm::cptr<CellDmuxResourceEx> resEx, vm::cptr<CellDmuxCb> cb, vm::ptr<u32> handle)
s32 cellDmuxOpenExt(vm::cptr<CellDmuxType> type, vm::cptr<CellDmuxResourceEx> resEx, vm::cptr<CellDmuxCb> cb, vm::ptr<u32> handle)
{
cellDmux.Warning("cellDmuxOpenExt(type=*0x%x, resEx=*0x%x, cb=*0x%x, handle=*0x%x)", type, resEx, cb, handle);
return cellDmuxOpenEx(type, resEx, cb, handle);
}
@ -1184,7 +1186,7 @@ Module cellDmux("cellDmux", []()
REG_FUNC(cellDmux, cellDmuxQueryAttr2);
REG_FUNC(cellDmux, cellDmuxOpen);
REG_FUNC(cellDmux, cellDmuxOpenEx);
REG_UNNAMED(cellDmux, e075fabc);
REG_FUNC(cellDmux, cellDmuxOpenExt); // 0xe075fabc
REG_FUNC(cellDmux, cellDmuxOpen2);
REG_FUNC(cellDmux, cellDmuxClose);
REG_FUNC(cellDmux, cellDmuxSetStream);

View file

@ -769,9 +769,9 @@ s32 cellVdecGetPicture(u32 handle, vm::cptr<CellVdecPicFormat> format, vm::ptr<u
return CELL_OK;
}
s32 _nid_a21aa896(PPUThread& CPU, u32 handle, vm::cptr<CellVdecPicFormat2> format2, vm::ptr<u8> outBuff, u32 arg4)
s32 cellVdecGetPictureExt(PPUThread& CPU, u32 handle, vm::cptr<CellVdecPicFormat2> format2, vm::ptr<u8> outBuff, u32 arg4)
{
cellVdec.Warning("_nid_a21aa896(handle=0x%x, format2=*0x%x, outBuff=*0x%x, arg4=*0x%x)", handle, format2, outBuff, arg4);
cellVdec.Warning("cellVdecGetPictureExt(handle=0x%x, format2=*0x%x, outBuff=*0x%x, arg4=*0x%x)", handle, format2, outBuff, arg4);
if (arg4 || format2->unk0 || format2->unk1)
{
@ -956,12 +956,16 @@ Module cellVdec("cellVdec", []()
REG_FUNC(cellVdec, cellVdecQueryAttrEx);
REG_FUNC(cellVdec, cellVdecOpen);
REG_FUNC(cellVdec, cellVdecOpenEx);
//REG_FUNC(cellVdec, cellVdecOpenExt); // 0xef4d8ad7
REG_FUNC(cellVdec, cellVdecClose);
REG_FUNC(cellVdec, cellVdecStartSeq);
//REG_FUNC(cellVdec, cellVdecStartSeqExt); // 0xebb8e70a
REG_FUNC(cellVdec, cellVdecEndSeq);
REG_FUNC(cellVdec, cellVdecDecodeAu);
REG_FUNC(cellVdec, cellVdecGetPicture);
REG_UNNAMED(cellVdec, a21aa896);
REG_FUNC(cellVdec, cellVdecGetPictureExt); // 0xa21aa896
REG_FUNC(cellVdec, cellVdecGetPicItem);
//REG_FUNC(cellVdec, cellVdecGetPicItemExt); // 0x2cbd9806
REG_FUNC(cellVdec, cellVdecSetFrameRate);
//REG_FUNC(cellVdec, cellVdecSetFrameRateExt); // 0xcffc42a5
});

View file

@ -142,6 +142,7 @@ Module cellVpost("cellVpost", []()
REG_FUNC(cellVpost, cellVpostQueryAttr);
REG_FUNC(cellVpost, cellVpostOpen);
REG_FUNC(cellVpost, cellVpostOpenEx);
//REG_FUNC(cellVpost, cellVpostOpenExt); // 0x9f1795df
REG_FUNC(cellVpost, cellVpostClose);
REG_FUNC(cellVpost, cellVpostExec);
});

View file

@ -5,6 +5,7 @@
#include "Emu/SysCalls/SysCalls.h"
#include "Emu/Cell/PPUThread.h"
#include "Emu/Cell/SPUThread.h"
#include "Emu/Event.h"
#include "sys_process.h"
#include "sys_event.h"
@ -27,16 +28,48 @@ void lv2_event_queue_t::push(lv2_lock_t& lv2_lock, u64 source, u64 data1, u64 da
{
CHECK_LV2_LOCK(lv2_lock);
events.emplace_back(source, data1, data2, data3);
// save event if no waiters
if (sq.empty())
{
return events.emplace_back(source, data1, data2, data3);
}
if (events.size())
{
throw EXCEPTION("Unexpected");
}
// notify waiter; protocol is ignored in current implementation
for (auto& waiter : sq)
auto& thread = sq.front();
if (type == SYS_PPU_QUEUE && thread->get_type() == CPU_THREAD_PPU)
{
if (waiter->signal())
{
return;
}
// store event data in registers
auto& ppu = static_cast<PPUThread&>(*thread);
ppu.GPR[4] = source;
ppu.GPR[5] = data1;
ppu.GPR[6] = data2;
ppu.GPR[7] = data3;
}
else if (type == SYS_SPU_QUEUE && thread->get_type() == CPU_THREAD_SPU)
{
// store event data in In_MBox
auto& spu = static_cast<SPUThread&>(*thread);
spu.ch_in_mbox.set_values(4, CELL_OK, static_cast<u32>(data1), static_cast<u32>(data2), static_cast<u32>(data3));
}
else
{
throw EXCEPTION("Unexpected (queue_type=%d, thread_type=%d)", type, thread->get_type());
}
if (!sq.front()->signal())
{
throw EXCEPTION("Thread already signaled");
}
return sq.pop_front();
}
s32 sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attribute_t> attr, u64 event_queue_key, s32 size)
@ -106,6 +139,19 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode)
// signal all threads to return CELL_ECANCELED
for (auto& thread : queue->sq)
{
if (queue->type == SYS_PPU_QUEUE && thread->get_type() == CPU_THREAD_PPU)
{
static_cast<PPUThread&>(*thread).GPR[3] = 1;
}
else if (queue->type == SYS_SPU_QUEUE && thread->get_type() == CPU_THREAD_SPU)
{
static_cast<SPUThread&>(*thread).ch_in_mbox.set_values(1, CELL_ECANCELED);
}
else
{
throw EXCEPTION("Unexpected (queue_type=%d, thread_type=%d)", queue->type, thread->get_type());
}
thread->signal();
}
@ -171,34 +217,44 @@ s32 sys_event_queue_receive(PPUThread& ppu, u32 equeue_id, vm::ptr<sys_event_t>
return CELL_EINVAL;
}
if (queue->events.empty() || !queue->sq.empty())
if (queue->events.size())
{
// add waiter; protocol is ignored in current implementation
sleep_queue_entry_t waiter(ppu, queue->sq);
// event data is returned in registers (dummy_event is not used)
std::tie(ppu.GPR[4], ppu.GPR[5], ppu.GPR[6], ppu.GPR[7]) = queue->events.front();
while (!ppu.unsignal())
queue->events.pop_front();
return CELL_OK;
}
// cause (if cancelled) will be returned in r3
ppu.GPR[3] = 0;
// add waiter; protocol is ignored in current implementation
sleep_queue_entry_t waiter(ppu, queue->sq);
while (!ppu.unsignal())
{
CHECK_EMU_STATUS;
if (timeout)
{
CHECK_EMU_STATUS;
const u64 passed = get_system_time() - start_time;
if (timeout)
if (passed >= timeout)
{
const u64 passed = get_system_time() - start_time;
if (passed >= timeout)
{
return CELL_ETIMEDOUT;
}
ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed));
}
else
{
ppu.cv.wait(lv2_lock);
return CELL_ETIMEDOUT;
}
ppu.cv.wait_for(lv2_lock, std::chrono::microseconds(timeout - passed));
}
else
{
ppu.cv.wait(lv2_lock);
}
}
if (queue->events.empty())
if (ppu.GPR[3])
{
if (Emu.GetIdManager().check_id<lv2_event_queue_t>(equeue_id))
{
@ -208,11 +264,7 @@ s32 sys_event_queue_receive(PPUThread& ppu, u32 equeue_id, vm::ptr<sys_event_t>
return CELL_ECANCELED;
}
// event data is returned in registers (dummy_event is not used)
std::tie(ppu.GPR[4], ppu.GPR[5], ppu.GPR[6], ppu.GPR[7]) = queue->events.front();
queue->events.pop_front();
// r4-r7 registers must be set by push()
return CELL_OK;
}