sys_event: add vm::temporary_unlock

This commit is contained in:
Nekotekina 2019-07-14 18:06:02 +03:00
parent cbfa6cc91f
commit 0a88a23bf5
4 changed files with 44 additions and 24 deletions

View File

@ -705,7 +705,7 @@ void _spurs::event_helper_entry(ppu_thread& ppu, vm::ptr<CellSpurs> spurs)
events[0].data2 = event_data2; events[0].data2 = event_data2;
events[0].data3 = event_data3; events[0].data3 = event_data3;
if (sys_event_queue_tryreceive(spurs->eventQueue, events + 1, 7, count) != CELL_OK) if (sys_event_queue_tryreceive(ppu, spurs->eventQueue, events + 1, 7, count) != CELL_OK)
{ {
continue; continue;
} }
@ -783,7 +783,7 @@ s32 _spurs::create_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs, u32 p
if (s32 rc = sys_event_port_connect_local(spurs->eventPort, spurs->eventQueue)) if (s32 rc = sys_event_port_connect_local(spurs->eventPort, spurs->eventQueue))
{ {
sys_event_port_destroy(spurs->eventPort); sys_event_port_destroy(ppu, spurs->eventPort);
if (s32 rc2 = _spurs::detach_lv2_eq(spurs, spurs->spuPort, true)) if (s32 rc2 = _spurs::detach_lv2_eq(spurs, spurs->spuPort, true))
{ {
@ -808,8 +808,8 @@ s32 _spurs::create_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs, u32 p
//if (!eht) //if (!eht)
{ {
sys_event_port_disconnect(spurs->eventPort); sys_event_port_disconnect(ppu, spurs->eventPort);
sys_event_port_destroy(spurs->eventPort); sys_event_port_destroy(ppu, spurs->eventPort);
if (s32 rc = _spurs::detach_lv2_eq(spurs, spurs->spuPort, true)) if (s32 rc = _spurs::detach_lv2_eq(spurs, spurs->spuPort, true))
{ {
@ -894,8 +894,8 @@ s32 _spurs::stop_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs)
spurs->ppu1 = 0xFFFFFFFF; spurs->ppu1 = 0xFFFFFFFF;
CHECK_SUCCESS(sys_event_port_disconnect(spurs->eventPort)); CHECK_SUCCESS(sys_event_port_disconnect(ppu, spurs->eventPort));
CHECK_SUCCESS(sys_event_port_destroy(spurs->eventPort)); CHECK_SUCCESS(sys_event_port_destroy(ppu, spurs->eventPort));
CHECK_SUCCESS(_spurs::detach_lv2_eq(spurs, spurs->spuPort, true)); CHECK_SUCCESS(_spurs::detach_lv2_eq(spurs, spurs->spuPort, true));
CHECK_SUCCESS(sys_event_queue_destroy(ppu, spurs->eventQueue, SYS_EVENT_QUEUE_DESTROY_FORCE)); CHECK_SUCCESS(sys_event_queue_destroy(ppu, spurs->eventQueue, SYS_EVENT_QUEUE_DESTROY_FORCE));
@ -3071,7 +3071,7 @@ s32 cellSpursEventFlagAttachLv2EventQueue(ppu_thread& ppu, vm::ptr<CellSpursEven
return success(), CELL_OK; return success(), CELL_OK;
} }
sys_event_port_destroy(*eventPortId); sys_event_port_destroy(ppu, *eventPortId);
} }
if (_spurs::detach_lv2_eq(spurs, *port, true) == CELL_OK) if (_spurs::detach_lv2_eq(spurs, *port, true) == CELL_OK)
@ -3132,8 +3132,8 @@ s32 cellSpursEventFlagDetachLv2EventQueue(ppu_thread& ppu, vm::ptr<CellSpursEven
if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY) if (eventFlag->direction == CELL_SPURS_EVENT_FLAG_ANY2ANY)
{ {
sys_event_port_disconnect(eventFlag->eventPortId); sys_event_port_disconnect(ppu, eventFlag->eventPortId);
sys_event_port_destroy(eventFlag->eventPortId); sys_event_port_destroy(ppu, eventFlag->eventPortId);
} }
s32 rc = _spurs::detach_lv2_eq(spurs, port, true); s32 rc = _spurs::detach_lv2_eq(spurs, port, true);

View File

@ -10,8 +10,6 @@
#include "Emu/Cell/SPUThread.h" #include "Emu/Cell/SPUThread.h"
#include "sys_process.h" #include "sys_process.h"
LOG_CHANNEL(sys_event); LOG_CHANNEL(sys_event);
template<> DECLARE(ipc_manager<lv2_event_queue, u64>::g_ipc) {}; template<> DECLARE(ipc_manager<lv2_event_queue, u64>::g_ipc) {};
@ -76,6 +74,8 @@ bool lv2_event_queue::send(lv2_event event)
error_code sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attribute_t> attr, u64 event_queue_key, s32 size) error_code sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attribute_t> attr, u64 event_queue_key, s32 size)
{ {
vm::temporary_unlock();
sys_event.warning("sys_event_queue_create(equeue_id=*0x%x, attr=*0x%x, event_queue_key=0x%llx, size=%d)", equeue_id, attr, event_queue_key, size); sys_event.warning("sys_event_queue_create(equeue_id=*0x%x, attr=*0x%x, event_queue_key=0x%llx, size=%d)", equeue_id, attr, event_queue_key, size);
if (size <= 0 || size > 127) if (size <= 0 || size > 127)
@ -138,6 +138,8 @@ error_code sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queu
error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode) error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
{ {
vm::temporary_unlock(ppu);
sys_event.warning("sys_event_queue_destroy(equeue_id=0x%x, mode=%d)", equeue_id, mode); sys_event.warning("sys_event_queue_destroy(equeue_id=0x%x, mode=%d)", equeue_id, mode);
if (mode && mode != SYS_EVENT_QUEUE_DESTROY_FORCE) if (mode && mode != SYS_EVENT_QUEUE_DESTROY_FORCE)
@ -190,8 +192,10 @@ error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode)
return CELL_OK; return CELL_OK;
} }
error_code sys_event_queue_tryreceive(u32 equeue_id, vm::ptr<sys_event_t> event_array, s32 size, vm::ptr<u32> number) error_code sys_event_queue_tryreceive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_event_t> event_array, s32 size, vm::ptr<u32> number)
{ {
vm::temporary_unlock(ppu);
sys_event.trace("sys_event_queue_tryreceive(equeue_id=0x%x, event_array=*0x%x, size=%d, number=*0x%x)", equeue_id, event_array, size, number); sys_event.trace("sys_event_queue_tryreceive(equeue_id=0x%x, event_array=*0x%x, size=%d, number=*0x%x)", equeue_id, event_array, size, number);
const auto queue = idm::get<lv2_obj, lv2_event_queue>(equeue_id); const auto queue = idm::get<lv2_obj, lv2_event_queue>(equeue_id);
@ -226,6 +230,8 @@ error_code sys_event_queue_tryreceive(u32 equeue_id, vm::ptr<sys_event_t> event_
error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_event_t> dummy_event, u64 timeout) error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_event_t> dummy_event, u64 timeout)
{ {
vm::temporary_unlock(ppu);
sys_event.trace("sys_event_queue_receive(equeue_id=0x%x, *0x%x, timeout=0x%llx)", equeue_id, dummy_event, timeout); sys_event.trace("sys_event_queue_receive(equeue_id=0x%x, *0x%x, timeout=0x%llx)", equeue_id, dummy_event, timeout);
ppu.gpr[3] = CELL_OK; ppu.gpr[3] = CELL_OK;
@ -305,8 +311,10 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_e
return not_an_error(ppu.gpr[3]); return not_an_error(ppu.gpr[3]);
} }
error_code sys_event_queue_drain(u32 equeue_id) error_code sys_event_queue_drain(ppu_thread& ppu, u32 equeue_id)
{ {
vm::temporary_unlock(ppu);
sys_event.trace("sys_event_queue_drain(equeue_id=0x%x)", equeue_id); sys_event.trace("sys_event_queue_drain(equeue_id=0x%x)", equeue_id);
const auto queue = idm::check<lv2_obj, lv2_event_queue>(equeue_id, [&](lv2_event_queue& queue) const auto queue = idm::check<lv2_obj, lv2_event_queue>(equeue_id, [&](lv2_event_queue& queue)
@ -326,6 +334,8 @@ error_code sys_event_queue_drain(u32 equeue_id)
error_code sys_event_port_create(vm::ptr<u32> eport_id, s32 port_type, u64 name) error_code sys_event_port_create(vm::ptr<u32> eport_id, s32 port_type, u64 name)
{ {
vm::temporary_unlock();
sys_event.warning("sys_event_port_create(eport_id=*0x%x, port_type=%d, name=0x%llx)", eport_id, port_type, name); sys_event.warning("sys_event_port_create(eport_id=*0x%x, port_type=%d, name=0x%llx)", eport_id, port_type, name);
if (port_type != SYS_EVENT_PORT_LOCAL && port_type != 3) if (port_type != SYS_EVENT_PORT_LOCAL && port_type != 3)
@ -343,8 +353,10 @@ error_code sys_event_port_create(vm::ptr<u32> eport_id, s32 port_type, u64 name)
return CELL_EAGAIN; return CELL_EAGAIN;
} }
error_code sys_event_port_destroy(u32 eport_id) error_code sys_event_port_destroy(ppu_thread& ppu, u32 eport_id)
{ {
vm::temporary_unlock(ppu);
sys_event.warning("sys_event_port_destroy(eport_id=0x%x)", eport_id); sys_event.warning("sys_event_port_destroy(eport_id=0x%x)", eport_id);
const auto port = idm::withdraw<lv2_obj, lv2_event_port>(eport_id, [](lv2_event_port& port) -> CellError const auto port = idm::withdraw<lv2_obj, lv2_event_port>(eport_id, [](lv2_event_port& port) -> CellError
@ -372,6 +384,8 @@ error_code sys_event_port_destroy(u32 eport_id)
error_code sys_event_port_connect_local(u32 eport_id, u32 equeue_id) error_code sys_event_port_connect_local(u32 eport_id, u32 equeue_id)
{ {
vm::temporary_unlock();
sys_event.warning("sys_event_port_connect_local(eport_id=0x%x, equeue_id=0x%x)", eport_id, equeue_id); sys_event.warning("sys_event_port_connect_local(eport_id=0x%x, equeue_id=0x%x)", eport_id, equeue_id);
std::lock_guard lock(id_manager::g_mutex); std::lock_guard lock(id_manager::g_mutex);
@ -398,8 +412,10 @@ error_code sys_event_port_connect_local(u32 eport_id, u32 equeue_id)
return CELL_OK; return CELL_OK;
} }
error_code sys_event_port_connect_ipc(u32 eport_id, u64 ipc_key) error_code sys_event_port_connect_ipc(ppu_thread& ppu, u32 eport_id, u64 ipc_key)
{ {
vm::temporary_unlock(ppu);
sys_event.warning("sys_event_port_connect_ipc(eport_id=0x%x, ipc_key=0x%x)", eport_id, ipc_key); sys_event.warning("sys_event_port_connect_ipc(eport_id=0x%x, ipc_key=0x%x)", eport_id, ipc_key);
auto queue = lv2_event_queue::find(ipc_key); auto queue = lv2_event_queue::find(ipc_key);
@ -428,8 +444,10 @@ error_code sys_event_port_connect_ipc(u32 eport_id, u64 ipc_key)
return CELL_OK; return CELL_OK;
} }
error_code sys_event_port_disconnect(u32 eport_id) error_code sys_event_port_disconnect(ppu_thread& ppu, u32 eport_id)
{ {
vm::temporary_unlock(ppu);
sys_event.warning("sys_event_port_disconnect(eport_id=0x%x)", eport_id); sys_event.warning("sys_event_port_disconnect(eport_id=0x%x)", eport_id);
std::lock_guard lock(id_manager::g_mutex); std::lock_guard lock(id_manager::g_mutex);
@ -455,6 +473,8 @@ error_code sys_event_port_disconnect(u32 eport_id)
error_code sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3) error_code sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3)
{ {
vm::temporary_unlock();
sys_event.trace("sys_event_port_send(eport_id=0x%x, data1=0x%llx, data2=0x%llx, data3=0x%llx)", eport_id, data1, data2, data3); sys_event.trace("sys_event_port_send(eport_id=0x%x, data1=0x%llx, data2=0x%llx, data3=0x%llx)", eport_id, data1, data2, data3);
const auto port = idm::get<lv2_obj, lv2_event_port>(eport_id, [&](lv2_event_port& port) -> CellError const auto port = idm::get<lv2_obj, lv2_event_port>(eport_id, [&](lv2_event_port& port) -> CellError

View File

@ -132,12 +132,12 @@ class ppu_thread;
error_code sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attribute_t> attr, u64 event_queue_key, s32 size); error_code sys_event_queue_create(vm::ptr<u32> equeue_id, vm::ptr<sys_event_queue_attribute_t> attr, u64 event_queue_key, s32 size);
error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode); error_code sys_event_queue_destroy(ppu_thread& ppu, u32 equeue_id, s32 mode);
error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_event_t> dummy_event, u64 timeout); error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_event_t> dummy_event, u64 timeout);
error_code sys_event_queue_tryreceive(u32 equeue_id, vm::ptr<sys_event_t> event_array, s32 size, vm::ptr<u32> number); error_code sys_event_queue_tryreceive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_event_t> event_array, s32 size, vm::ptr<u32> number);
error_code sys_event_queue_drain(u32 event_queue_id); error_code sys_event_queue_drain(ppu_thread& ppu, u32 event_queue_id);
error_code sys_event_port_create(vm::ptr<u32> eport_id, s32 port_type, u64 name); error_code sys_event_port_create(vm::ptr<u32> eport_id, s32 port_type, u64 name);
error_code sys_event_port_destroy(u32 eport_id); error_code sys_event_port_destroy(ppu_thread& ppu, u32 eport_id);
error_code sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id); error_code sys_event_port_connect_local(u32 event_port_id, u32 event_queue_id);
error_code sys_event_port_connect_ipc(u32 eport_id, u64 ipc_key); error_code sys_event_port_connect_ipc(ppu_thread& ppu, u32 eport_id, u64 ipc_key);
error_code sys_event_port_disconnect(u32 eport_id); error_code sys_event_port_disconnect(ppu_thread& ppu, u32 eport_id);
error_code sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3); error_code sys_event_port_send(u32 event_port_id, u64 data1, u64 data2, u64 data3);

View File

@ -445,7 +445,7 @@ error_code sys_mmapper_enable_page_fault_notification(ppu_thread& ppu, u32 start
vm::var<u32> port_id(0); vm::var<u32> port_id(0);
error_code res = sys_event_port_create(port_id, SYS_EVENT_PORT_LOCAL, SYS_MEMORY_PAGE_FAULT_EVENT_KEY); error_code res = sys_event_port_create(port_id, SYS_EVENT_PORT_LOCAL, SYS_MEMORY_PAGE_FAULT_EVENT_KEY);
sys_event_port_connect_local(port_id->value(), event_queue_id); sys_event_port_connect_local(*port_id, event_queue_id);
if (res == CELL_EAGAIN) if (res == CELL_EAGAIN)
{ // Not enough system resources. { // Not enough system resources.
@ -461,8 +461,8 @@ error_code sys_mmapper_enable_page_fault_notification(ppu_thread& ppu, u32 start
if (entry.start_addr == start_addr) if (entry.start_addr == start_addr)
{ {
lock.unlock(); lock.unlock();
sys_event_port_disconnect(port_id->value()); sys_event_port_disconnect(ppu, *port_id);
sys_event_port_destroy(port_id->value()); sys_event_port_destroy(ppu, *port_id);
return CELL_EBUSY; return CELL_EBUSY;
} }
} }