From 7d8993862471ff4d81f927e78c7b64f8d4b9cc7f Mon Sep 17 00:00:00 2001 From: Eladash Date: Fri, 28 May 2021 12:35:03 +0300 Subject: [PATCH] cellPad: do not use recusrive mutex --- rpcs3/Emu/Cell/Modules/cellPad.cpp | 56 +++++++++++++----------------- rpcs3/Input/pad_thread.cpp | 2 +- rpcs3/Input/pad_thread.h | 3 +- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellPad.cpp b/rpcs3/Emu/Cell/Modules/cellPad.cpp index e36e705754..7a8e3b3263 100644 --- a/rpcs3/Emu/Cell/Modules/cellPad.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPad.cpp @@ -137,6 +137,8 @@ error_code cellPadClearBuf(u32 port_no) return CELL_OK; } +void pad_get_data(u32 port_no, CellPadData* data); + error_code cellPadGetData(u32 port_no, vm::ptr data) { sys_io.trace("cellPadGetData(port_no=%d, data=*0x%x)", port_no, data); @@ -163,12 +165,21 @@ error_code cellPadGetData(u32 port_no, vm::ptr data) if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) return CELL_PAD_ERROR_NO_DEVICE; + pad_get_data(port_no, data.get_ptr()); + return CELL_OK; +} + +void pad_get_data(u32 port_no, CellPadData* data) +{ + auto& config = g_fxo->get(); + const auto handler = pad::get_current_handler(); + const auto& pad = handler->GetPads()[port_no]; const PadInfo& rinfo = handler->GetInfo(); if (rinfo.system_info & CELL_PAD_INFO_INTERCEPTED) { data->len = CELL_PAD_LEN_NO_CHANGE; - return CELL_OK; + return; } const auto setting = config.port_setting[port_no]; @@ -182,12 +193,12 @@ error_code cellPadGetData(u32 port_no, vm::ptr data) } else if (pad->ldd) { - memcpy(data.get_ptr(), pad->ldd_data, sizeof(CellPadData)); + std::memcpy(data, pad->ldd_data, sizeof(CellPadData)); if (setting & CELL_PAD_SETTING_SENSOR_ON) data->len = CELL_PAD_LEN_CHANGE_SENSOR_ON; else data->len = (setting & CELL_PAD_SETTING_PRESS_ON) ? CELL_PAD_LEN_CHANGE_PRESS_ON : CELL_PAD_LEN_CHANGE_DEFAULT; - return CELL_OK; + return; } else { @@ -409,8 +420,6 @@ error_code cellPadGetData(u32 port_no, vm::ptr data) data->button[CELL_PAD_BTN_OFFSET_SENSOR_G] = pad->m_sensor_g; } } - - return CELL_OK; } error_code cellPadPeriphGetInfo(vm::ptr info) @@ -478,16 +487,18 @@ error_code cellPadPeriphGetData(u32 port_no, vm::ptr data) if (port_no >= config.max_connect) return CELL_PAD_ERROR_NO_DEVICE; - const auto pad = pads[port_no]; + const auto& pad = pads[port_no]; if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) return CELL_PAD_ERROR_NO_DEVICE; + pad_get_data(port_no, &data->cellpad_data); + data->pclass_type = pad->m_class_type; data->pclass_profile = pad->m_class_profile; // TODO: support for 'unique' controllers, which goes in offsets 24+ in padData (CELL_PAD_PCLASS_BTN_OFFSET) - return cellPadGetData(port_no, data.ptr(&CellPadPeriphData::cellpad_data)); + return CELL_OK; } error_code cellPadGetRawData(u32 port_no, vm::ptr data) @@ -525,41 +536,24 @@ error_code cellPadGetDataExtra(u32 port_no, vm::ptr device_type, vm::ptrget(); - - if (!config.max_connect) - return CELL_PAD_ERROR_UNINITIALIZED; - - const auto handler = pad::get_current_handler(); - - if (port_no >= CELL_MAX_PADS || !data) - return CELL_PAD_ERROR_INVALID_PARAMETER; - - const auto& pads = handler->GetPads(); - - if (port_no >= config.max_connect) - return CELL_PAD_ERROR_NO_DEVICE; - - const auto pad = pads[port_no]; - - if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED)) - return CELL_PAD_ERROR_NO_DEVICE; - // TODO: This is used just to get data from a BD/CEC remote, // but if the port isnt a remote, device type is set to 0 and just regular cellPadGetData is returned + if (auto err = cellPadGetData(port_no, data)) + { + return err; + } + if (device_type) // no error is returned on NULL { *device_type = 0; } - // set BD data before just incase + // Set BD data data->button[24] = 0x0; data->button[25] = 0x0; - return cellPadGetData(port_no, data); + return CELL_OK; } error_code cellPadSetActDirect(u32 port_no, vm::ptr param) diff --git a/rpcs3/Input/pad_thread.cpp b/rpcs3/Input/pad_thread.cpp index ce3be8bb5e..911479a6b0 100644 --- a/rpcs3/Input/pad_thread.cpp +++ b/rpcs3/Input/pad_thread.cpp @@ -20,7 +20,7 @@ LOG_CHANNEL(input_log, "Input"); namespace pad { atomic_t g_current = nullptr; - std::recursive_mutex g_pad_mutex; + shared_mutex g_pad_mutex; std::string g_title_id; atomic_t g_reset{false}; atomic_t g_enabled{true}; diff --git a/rpcs3/Input/pad_thread.h b/rpcs3/Input/pad_thread.h index d4a79d7136..b78d8a97bc 100644 --- a/rpcs3/Input/pad_thread.h +++ b/rpcs3/Input/pad_thread.h @@ -4,6 +4,7 @@ #include "util/atomic.hpp" #include "Emu/Io/pad_types.h" #include "Emu/Io/pad_config_types.h" +#include "Utilities/mutex.h" #include #include @@ -52,7 +53,7 @@ protected: namespace pad { extern atomic_t g_current; - extern std::recursive_mutex g_pad_mutex; + extern shared_mutex g_pad_mutex; extern std::string g_title_id; extern atomic_t g_enabled; extern atomic_t g_reset;