sceNpUtil: implement skeleton bandwidth test

This commit is contained in:
Megamouse 2022-05-30 22:24:25 +02:00
parent 74a909cfbc
commit f4e85af53c
2 changed files with 106 additions and 26 deletions

View File

@ -7,46 +7,125 @@
LOG_CHANNEL(sceNpUtil); LOG_CHANNEL(sceNpUtil);
error_code sceNpUtilBandwidthTestInitStart(u32 prio, u64 stack) struct bandwidth_test
{
atomic_t<u32> status = SCE_NP_UTIL_BANDWIDTH_TEST_STATUS_NONE;
atomic_t<bool> abort = false;
atomic_t<bool> shutdown = false;
atomic_t<bool> finished = false;
SceNpUtilBandwidthTestResult test_result{};
static constexpr auto thread_name = "HLE SceNpBandwidthTest"sv;
void operator()()
{
status = SCE_NP_UTIL_BANDWIDTH_TEST_STATUS_RUNNING;
u32 fake_sleep_count = 0;
while (thread_ctrl::state() != thread_state::aborting)
{
if (abort || shutdown)
{
break;
}
// TODO: run proper bandwidth test, probably with cellHttp
thread_ctrl::wait_for(1000); // wait 1ms
if (fake_sleep_count++ > 100) // end fake bandwidth test after 100 ms
{
break;
}
}
test_result.upload_bps = 16000.0;
test_result.download_bps = 16000.0;
test_result.result = CELL_OK;
status = SCE_NP_UTIL_BANDWIDTH_TEST_STATUS_FINISHED;
finished = true;
}
};
struct sce_np_util_manager
{
shared_mutex mtx{};
std::unique_ptr<named_thread<bandwidth_test>> bandwidth_test_thread;
~sce_np_util_manager()
{
join_thread();
}
void join_thread()
{
if (bandwidth_test_thread)
{
auto& thread = *bandwidth_test_thread;
thread = thread_state::aborting;
thread();
bandwidth_test_thread.reset();
}
}
};
error_code sceNpUtilBandwidthTestInitStart(ppu_thread& ppu, u32 prio, u32 stack)
{ {
sceNpUtil.todo("sceNpUtilBandwidthTestInitStart(prio=%d, stack=%d)", prio, stack); sceNpUtil.todo("sceNpUtilBandwidthTestInitStart(prio=%d, stack=%d)", prio, stack);
auto& util_manager = g_fxo->get<sce_np_util_manager>(); auto& util_manager = g_fxo->get<sce_np_util_manager>();
std::lock_guard lock(util_manager.mtx);
if (util_manager.is_initialized) if (util_manager.bandwidth_test_thread)
{ {
return SCE_NP_ERROR_ALREADY_INITIALIZED; return SCE_NP_ERROR_ALREADY_INITIALIZED;
} }
util_manager.is_initialized = true; util_manager.bandwidth_test_thread = std::make_unique<named_thread<bandwidth_test>>();
return CELL_OK; return CELL_OK;
} }
error_code sceNpUtilBandwidthTestGetStatus() error_code sceNpUtilBandwidthTestGetStatus()
{ {
sceNpUtil.todo("sceNpUtilBandwidthTestGetStatus()"); sceNpUtil.notice("sceNpUtilBandwidthTestGetStatus()");
if (!g_fxo->get<sce_np_util_manager>().is_initialized)
{
return SCE_NP_ERROR_NOT_INITIALIZED;
}
return not_an_error(SCE_NP_UTIL_BANDWIDTH_TEST_STATUS_FINISHED);
}
error_code sceNpUtilBandwidthTestShutdown(vm::ptr<SceNpUtilBandwidthTestResult> result)
{
sceNpUtil.todo("sceNpUtilBandwidthTestShutdown(result=*0x%x)", result);
auto& util_manager = g_fxo->get<sce_np_util_manager>(); auto& util_manager = g_fxo->get<sce_np_util_manager>();
std::lock_guard lock(util_manager.mtx);
if (!util_manager.is_initialized) if (!util_manager.bandwidth_test_thread)
{ {
return SCE_NP_ERROR_NOT_INITIALIZED; return SCE_NP_ERROR_NOT_INITIALIZED;
} }
util_manager.is_initialized = false; return not_an_error(util_manager.bandwidth_test_thread->status);
}
error_code sceNpUtilBandwidthTestShutdown(ppu_thread& ppu, vm::ptr<SceNpUtilBandwidthTestResult> result)
{
sceNpUtil.warning("sceNpUtilBandwidthTestShutdown(result=*0x%x)", result);
auto& util_manager = g_fxo->get<sce_np_util_manager>();
std::lock_guard lock(util_manager.mtx);
if (!util_manager.bandwidth_test_thread)
{
return SCE_NP_ERROR_NOT_INITIALIZED;
}
util_manager.bandwidth_test_thread->shutdown = true;
while (!util_manager.bandwidth_test_thread->finished)
{
thread_ctrl::wait_for(1000);
}
if (result) // TODO: what happens when this is null ?
{
*result = util_manager.bandwidth_test_thread->test_result;
}
util_manager.join_thread();
return CELL_OK; return CELL_OK;
} }
@ -55,11 +134,18 @@ error_code sceNpUtilBandwidthTestAbort()
{ {
sceNpUtil.todo("sceNpUtilBandwidthTestAbort()"); sceNpUtil.todo("sceNpUtilBandwidthTestAbort()");
if (!g_fxo->get<sce_np_util_manager>().is_initialized) auto& util_manager = g_fxo->get<sce_np_util_manager>();
std::lock_guard lock(util_manager.mtx);
if (!util_manager.bandwidth_test_thread)
{ {
return SCE_NP_ERROR_NOT_INITIALIZED; return SCE_NP_ERROR_NOT_INITIALIZED;
} }
// TODO: cellHttpTransactionAbortConnection();
util_manager.bandwidth_test_thread->abort = true;
return CELL_OK; return CELL_OK;
} }

View File

@ -12,11 +12,5 @@ struct SceNpUtilBandwidthTestResult
be_t<f64> upload_bps; be_t<f64> upload_bps;
be_t<f64> download_bps; be_t<f64> download_bps;
be_t<s32> result; be_t<s32> result;
}; s8 padding[4];
// fxm objects
struct sce_np_util_manager
{
atomic_t<bool> is_initialized = false;
}; };