1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-21 18:22:33 +01:00

Implement thread_ctrl::wait_until()

This commit is contained in:
Elad Ashkenazi 2024-08-16 20:06:20 +03:00
parent b2877365de
commit 1bd4565186
6 changed files with 47 additions and 11 deletions

View File

@ -1622,7 +1622,7 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe
error_code sending_error = not_an_error(CELL_EBUSY);
// If we fail due to being busy, wait a bit and try again.
for (; static_cast<u32>(sending_error) == CELL_EBUSY; thread_ctrl::wait_for(1000))
for (u64 sleep_until = get_system_time(); static_cast<u32>(sending_error) == CELL_EBUSY; thread_ctrl::wait_until(&sleep_until, 1000))
{
sending_error = send_event();
@ -2414,6 +2414,34 @@ void thread_ctrl::wait_for(u64 usec, [[maybe_unused]] bool alert /* true */)
list.wait(atomic_wait_timeout{usec <= 0xffff'ffff'ffff'ffff / 1000 ? usec * 1000 : 0xffff'ffff'ffff'ffff});
}
void thread_ctrl::wait_until(u64* wait_time, u64 add_time, u64 min_wait, bool update_to_current_time)
{
*wait_time = utils::add_saturate<u64>(*wait_time, add_time);
// TODO: Implement proper support for "waiting until" inside atomic wait engine
const u64 current_time = get_system_time();
if (current_time > *wait_time)
{
if (update_to_current_time)
{
*wait_time = current_time + (add_time - (current_time - *wait_time) % add_time);
}
else if (!min_wait)
{
return;
}
}
if (min_wait)
{
*wait_time = std::max<u64>(*wait_time, utils::add_saturate<u64>(current_time, min_wait));
}
wait_for(*wait_time - current_time);
}
void thread_ctrl::wait_for_accurate(u64 usec)
{
if (!usec)

View File

@ -276,6 +276,9 @@ public:
// Wait once with timeout. Infinite value is -1.
static void wait_for(u64 usec, bool alert = true);
// Wait once with time point, add_time is added to the time point.
static void wait_until(u64* wait_time, u64 add_time = 0, u64 min_wait = 0, bool update_to_current_time = true);
// Waiting with accurate timeout
static void wait_for_accurate(u64 usec);

View File

@ -1206,10 +1206,11 @@ public:
void operator()()
{
bool was_paused = false;
u64 sleep_until = get_system_time();
for (u32 i = 1; thread_ctrl::state() != thread_state::aborting; i++)
{
thread_ctrl::wait_for(1'000'000);
thread_ctrl::wait_until(&sleep_until, 1'000'000);
const bool is_paused = Emu.IsPaused();

View File

@ -894,7 +894,7 @@ void gdb_thread::operator()()
{
start_server();
while (server_socket != -1 && thread_ctrl::state() != thread_state::aborting)
for (u64 sleep_until = get_system_time(); server_socket != -1 && thread_ctrl::state() != thread_state::aborting;)
{
sockaddr_in client;
socklen_t client_len = sizeof(client);
@ -904,7 +904,7 @@ void gdb_thread::operator()()
{
if (check_errno_again())
{
thread_ctrl::wait_for(5000);
thread_ctrl::wait_until(&sleep_until, 5000);
continue;
}

View File

@ -20,10 +20,11 @@ void perf_monitor::operator()()
u64 last_pause_time = umax;
std::vector<double> per_core_usage;
std::string msg;
while (thread_ctrl::state() != thread_state::aborting)
for (u64 sleep_until = get_system_time(); thread_ctrl::state() != thread_state::aborting;)
{
thread_ctrl::wait_for(update_interval_us);
thread_ctrl::wait_until(&sleep_until, update_interval_us);
elapsed_us += update_interval_us;
if (thread_ctrl::state() == thread_state::aborting)
@ -61,14 +62,15 @@ void perf_monitor::operator()()
logged_pause++;
}
std::string msg = fmt::format("CPU Usage: Total: %.1f%%", total_usage);
msg.clear();
fmt::append(msg, "CPU Usage: Total: %.1f%%", total_usage);
if (!per_core_usage.empty())
{
fmt::append(msg, ", Cores:");
}
for (size_t i = 0; i < per_core_usage.size(); i++)
for (usz i = 0; i < per_core_usage.size(); i++)
{
fmt::append(msg, "%s %.1f%%", i > 0 ? "," : "", per_core_usage[i]);
}

View File

@ -175,7 +175,9 @@ void progress_dialog_server::operator()()
usz time_left_queue_idx = 0;
// Update progress
while (!g_system_progress_stopping && thread_ctrl::state() != thread_state::aborting)
for (u64 sleep_until = get_system_time(), sleep_for = 500;
!g_system_progress_stopping && thread_ctrl::state() != thread_state::aborting;
thread_ctrl::wait_until(&sleep_until, std::exchange(sleep_for, 500)))
{
const auto& [text_new, ftotal_new, fdone_new, ftotal_bits_new, fknown_bits_new, ptotal_new, pdone_new] = get_state();
@ -236,7 +238,7 @@ void progress_dialog_server::operator()()
}
}
thread_ctrl::wait_for(10000);
sleep_for = 10000;
continue;
}
@ -365,7 +367,7 @@ void progress_dialog_server::operator()()
break;
}
thread_ctrl::wait_for(10'000);
sleep_for = 10'000;
wait_no_update_count++;
}