Decrease memory stats in cellGemInit if needed

Also:
* fix state reset of cellGem
* Check max_connect == 0 in cellGemInit
This commit is contained in:
Eladash 2019-09-21 13:25:53 +03:00 committed by Megamouse
parent d91f8193b0
commit 3b06214f88

View file

@ -106,6 +106,7 @@ struct gem_config
u32 connected_controllers; u32 connected_controllers;
bool update_started{}; bool update_started{};
u32 camera_frame{}; u32 camera_frame{};
u32 memory_ptr{};
shared_mutex mtx; shared_mutex mtx;
@ -191,7 +192,7 @@ static bool check_gem_num(const u32 gem_num)
*/ */
static bool map_to_ds3_input(const u32 port_no, be_t<u16>& digital_buttons, be_t<u16>& analog_t) static bool map_to_ds3_input(const u32 port_no, be_t<u16>& digital_buttons, be_t<u16>& analog_t)
{ {
std::lock_guard lock(pad::g_pad_mutex); std::scoped_lock lock(pad::g_pad_mutex);
const auto handler = pad::get_current_handler(); const auto handler = pad::get_current_handler();
@ -279,7 +280,7 @@ static bool map_to_ds3_input(const u32 port_no, be_t<u16>& digital_buttons, be_t
*/ */
static bool map_ext_to_ds3_input(const u32 port_no, CellGemExtPortData& ext) static bool map_ext_to_ds3_input(const u32 port_no, CellGemExtPortData& ext)
{ {
std::lock_guard lock(pad::g_pad_mutex); std::scoped_lock lock(pad::g_pad_mutex);
const auto handler = pad::get_current_handler(); const auto handler = pad::get_current_handler();
@ -313,6 +314,8 @@ error_code cellGemCalibrate(u32 gem_num)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -338,6 +341,8 @@ error_code cellGemClearStatusFlags(u32 gem_num, u64 mask)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -387,6 +392,8 @@ error_code cellGemEnableCameraPitchAngleCorrection(u32 enable_flag)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -403,6 +410,8 @@ error_code cellGemEnableMagnetometer(u32 gem_num, u32 enable)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -430,20 +439,29 @@ error_code cellGemEnd()
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
if (!gem->state.compare_and_swap_test(1, 0)) std::scoped_lock lock(gem->mtx);
if (gem->state.compare_and_swap_test(1, 0))
{ {
return CELL_GEM_ERROR_UNINITIALIZED; if (u32 addr = gem->memory_ptr)
{
sys_memory_free(addr);
} }
return CELL_OK; return CELL_OK;
} }
return CELL_GEM_ERROR_UNINITIALIZED;
}
error_code cellGemFilterState(u32 gem_num, u32 enable) error_code cellGemFilterState(u32 gem_num, u32 enable)
{ {
cellGem.warning("cellGemFilterState(gem_num=%d, enable=%d)", gem_num, enable); cellGem.warning("cellGemFilterState(gem_num=%d, enable=%d)", gem_num, enable);
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -465,6 +483,8 @@ error_code cellGemForceRGB(u32 gem_num, float r, float g, float b)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -612,6 +632,8 @@ error_code cellGemGetInertialState(u32 gem_num, u32 state_flag, u64 timestamp, v
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -643,6 +665,8 @@ error_code cellGemGetInfo(vm::ptr<CellGemInfo> info)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -666,6 +690,11 @@ error_code cellGemGetInfo(vm::ptr<CellGemInfo> info)
return CELL_OK; return CELL_OK;
} }
u32 GemGetMemorySize(s32 max_connect)
{
return max_connect <= 2 ? 0x120000 : 0x140000;
}
error_code cellGemGetMemorySize(s32 max_connect) error_code cellGemGetMemorySize(s32 max_connect)
{ {
cellGem.warning("cellGemGetMemorySize(max_connect=%d)", max_connect); cellGem.warning("cellGemGetMemorySize(max_connect=%d)", max_connect);
@ -675,7 +704,7 @@ error_code cellGemGetMemorySize(s32 max_connect)
return CELL_GEM_ERROR_INVALID_PARAMETER; return CELL_GEM_ERROR_INVALID_PARAMETER;
} }
return not_an_error(max_connect <= 2 ? 0x120000 : 0x140000); return not_an_error(GemGetMemorySize(max_connect));
} }
error_code cellGemGetRGB(u32 gem_num, vm::ptr<float> r, vm::ptr<float> g, vm::ptr<float> b) error_code cellGemGetRGB(u32 gem_num, vm::ptr<float> r, vm::ptr<float> g, vm::ptr<float> b)
@ -684,6 +713,8 @@ error_code cellGemGetRGB(u32 gem_num, vm::ptr<float> r, vm::ptr<float> g, vm::pt
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -708,6 +739,8 @@ error_code cellGemGetRumble(u32 gem_num, vm::ptr<u8> rumble)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -729,6 +762,8 @@ error_code cellGemGetState(u32 gem_num, u32 flag, u64 time_parameter, vm::ptr<Ce
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -760,6 +795,8 @@ error_code cellGemGetStatusFlags(u32 gem_num, vm::ptr<u64> flags)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -781,6 +818,8 @@ error_code cellGemGetTrackerHue(u32 gem_num, vm::ptr<u32> hue)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::shared_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -823,19 +862,41 @@ error_code cellGemInit(vm::cptr<CellGemAttribute> attribute)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
if (!attribute || !attribute->spurs_addr || attribute->max_connect > CELL_GEM_MAX_NUM) if (!attribute || !attribute->spurs_addr || !attribute->max_connect || attribute->max_connect > CELL_GEM_MAX_NUM)
{ {
return CELL_GEM_ERROR_INVALID_PARAMETER; return CELL_GEM_ERROR_INVALID_PARAMETER;
} }
std::scoped_lock lock(gem->mtx);
if (!gem->state.compare_and_swap_test(0, 1)) if (!gem->state.compare_and_swap_test(0, 1))
{ {
return CELL_GEM_ERROR_ALREADY_INITIALIZED; return CELL_GEM_ERROR_ALREADY_INITIALIZED;
} }
if (!attribute->memory_ptr)
{
vm::var<u32> addr(0);
// Decrease memory stats
if (sys_memory_allocate(GemGetMemorySize(attribute->max_connect), SYS_MEMORY_PAGE_SIZE_64K, +addr) != CELL_OK)
{
return CELL_GEM_ERROR_RESOURCE_ALLOCATION_FAILED;
}
gem->memory_ptr = *addr;
}
else
{
gem->memory_ptr = 0;
}
gem->update_started = false;
gem->camera_frame = 0;
gem->status_flags = 0;
gem->attribute = *attribute; gem->attribute = *attribute;
for (auto gem_num = 0; gem_num < CELL_GEM_MAX_NUM; gem_num++) for (int gem_num = 0; gem_num < CELL_GEM_MAX_NUM; gem_num++)
{ {
gem->reset_controller(gem_num); gem->reset_controller(gem_num);
} }
@ -852,6 +913,8 @@ error_code cellGemInvalidateCalibration(s32 gem_num)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -997,6 +1060,8 @@ error_code cellGemSetRumble(u32 gem_num, u8 rumble)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;
@ -1024,6 +1089,8 @@ error_code cellGemTrackHues(vm::cptr<u32> req_hues, vm::ptr<u32> res_hues)
const auto gem = g_fxo->get<gem_config>(); const auto gem = g_fxo->get<gem_config>();
std::scoped_lock lock(gem->mtx);
if (!gem->state) if (!gem->state)
{ {
return CELL_GEM_ERROR_UNINITIALIZED; return CELL_GEM_ERROR_UNINITIALIZED;