From 85b63de63158e46e3ad456d50cd63ec2e0928190 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 13 Apr 2015 16:32:09 +0300 Subject: [PATCH] Events improved --- rpcs3/Emu/Cell/SPUThread.cpp | 4 +-- rpcs3/Emu/Event.cpp | 1 + rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_event.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_event.h | 4 ++- rpcs3/Emu/SysCalls/lv2/sys_spu.cpp | 5 +--- rpcs3/Emu/SysCalls/lv2/sys_spu.h | 32 +++++++++++++++++++++++- rpcs3/Emu/SysCalls/lv2/sys_timer.cpp | 2 +- rpcs3/Emu/System.h | 5 +++- 9 files changed, 45 insertions(+), 12 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 7468d41116..66652f4ad5 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -686,7 +686,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value) return ch_in_mbox.push_uncond(CELL_EBUSY); } - queue->push(SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (value & 0x00ffffff), data); + queue->push(lv2_lock, SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (value & 0x00ffffff), data); return ch_in_mbox.push_uncond(CELL_OK); } @@ -725,7 +725,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value) return; } - queue->push(SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (value & 0x00ffffff), data); + queue->push(lv2_lock, SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (value & 0x00ffffff), data); return; } else if (code == 128) diff --git a/rpcs3/Emu/Event.cpp b/rpcs3/Emu/Event.cpp index 4297aa2cad..29df4196fa 100644 --- a/rpcs3/Emu/Event.cpp +++ b/rpcs3/Emu/Event.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Emu/Memory/Memory.h" +#include "Emu/System.h" #include "Emu/SysCalls/lv2/sleep_queue.h" #include "Emu/SysCalls/lv2/sys_event.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 4ca9b72cb0..39cf506454 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -391,7 +391,7 @@ s32 cellAudioInit() { if (const auto queue = Emu.GetEventManager().GetEventQueue(key)) { - queue->push(0, 0, 0, 0); // TODO: check arguments + queue->push(lv2_lock, 0, 0, 0, 0); // TODO: check arguments } } } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp index 0fa40d34a5..fd26a033ee 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp @@ -345,7 +345,7 @@ s32 sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3) const u64 source = port->name ? port->name : ((u64)process_getpid() << 32) | (u64)eport_id; - queue->push(source, data1, data2, data3); + queue->push(lv2_lock, source, data1, data2, data3); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.h b/rpcs3/Emu/SysCalls/lv2/sys_event.h index 842d4b267a..d5e2045bda 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.h @@ -95,8 +95,10 @@ struct event_queue_t { } - void push(u64 source, u64 data1, u64 data2, u64 data3) + void push(lv2_lock_type& lv2_lock, u64 source, u64 data1, u64 data2, u64 data3) { + CHECK_LV2_LOCK(lv2_lock); + events.emplace_back(source, data1, data2, data3); if (waiters) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index eee7e4aa62..695b45c8f4 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -329,10 +329,7 @@ s32 sys_spu_thread_group_start(u32 id) // because SPU_THREAD_GROUP_STATUS_READY is not possible, run event is delivered immediately - if (auto queue = group->ep_run.lock()) - { - queue->push(SYS_SPU_THREAD_GROUP_EVENT_RUN_KEY, id, 0, 0); // TODO: check data2 and data3 - } + group->send_run_event(lv2_lock, id, 0, 0); // TODO: check data2 and data3 for (auto& t : group->threads) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.h b/rpcs3/Emu/SysCalls/lv2/sys_spu.h index cfa67f082c..45884f9744 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.h @@ -1,6 +1,6 @@ #pragma once -struct event_queue_t; +#include "sys_event.h" enum : s32 { @@ -172,6 +172,36 @@ struct spu_group_t , join_state(0) { } + + void send_run_event(lv2_lock_type& lv2_lock, u64 data1, u64 data2, u64 data3) + { + CHECK_LV2_LOCK(lv2_lock); + + if (const auto queue = ep_run.lock()) + { + queue->push(lv2_lock, SYS_SPU_THREAD_GROUP_EVENT_RUN_KEY, data1, data2, data3); + } + } + + void send_exception_event(lv2_lock_type& lv2_lock, u64 data1, u64 data2, u64 data3) + { + CHECK_LV2_LOCK(lv2_lock); + + if (const auto queue = ep_exception.lock()) + { + queue->push(lv2_lock, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION_KEY, data1, data2, data3); + } + } + + void send_sysmodule_event(lv2_lock_type& lv2_lock, u64 data1, u64 data2, u64 data3) + { + CHECK_LV2_LOCK(lv2_lock); + + if (const auto queue = ep_sysmodule.lock()) + { + queue->push(lv2_lock, SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE_KEY, data1, data2, data3); + } + } }; class SPUThread; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp index d0d45c19c8..2954aa29a5 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp @@ -32,7 +32,7 @@ s32 sys_timer_create(vm::ptr timer_id) if (queue) { - queue->push(timer->source, timer->data1, timer->data2, timer->start); + queue->push(lv2_lock, timer->source, timer->data1, timer->data2, timer->start); } if (timer->period && queue) diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index acd5db21e5..5798d3522a 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -199,7 +199,10 @@ public: __forceinline bool IsReady() const { return m_status == Ready; } }; -#define LV2_LOCK std::unique_lock lv2_lock(Emu.GetCoreMutex()) +using lv2_lock_type = std::unique_lock; + +#define LV2_LOCK lv2_lock_type lv2_lock(Emu.GetCoreMutex()) +#define CHECK_LV2_LOCK(x) assert((x).owns_lock() && (x).mutex() == &Emu.GetCoreMutex()) extern Emulator Emu;