mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-12-06 07:12:28 +01:00
SaveStates: Improve try_lock_spu_threads_in_a_state_compatible_with_savestates
This commit is contained in:
parent
a053abfba4
commit
1c0fa2ad58
|
|
@ -1585,22 +1585,30 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
|
||||||
|
|
||||||
idm::select<named_thread<spu_thread>>([&](u32 id, spu_thread& spu)
|
idm::select<named_thread<spu_thread>>([&](u32 id, spu_thread& spu)
|
||||||
{
|
{
|
||||||
spu_list.emplace_back(ensure(idm::get_unlocked<named_thread<spu_thread>>(id)));
|
if (give_up)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (spu.current_func && spu.unsavable)
|
if (spu.current_func && spu.unsavable && !force_collect)
|
||||||
{
|
{
|
||||||
const u64 start = spu.start_time;
|
const u64 start = spu.start_time;
|
||||||
|
|
||||||
// Automatically give up if it is asleep 15 seconds or more
|
// Automatically give up if it is asleep 5 seconds or more
|
||||||
if (start && current > start && current - start >= 15'000'000)
|
if (start && current > start && current - start >= 5'000'000)
|
||||||
{
|
{
|
||||||
give_up = true;
|
give_up = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spu_list.emplace_back(ensure(idm::get_unlocked<named_thread<spu_thread>>(id)));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!force_collect && give_up)
|
if (give_up)
|
||||||
{
|
{
|
||||||
|
spu_list.clear();
|
||||||
|
old_counter = umax;
|
||||||
return decltype(&spu_list){};
|
return decltype(&spu_list){};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1625,6 +1633,7 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
|
||||||
}
|
}
|
||||||
else if (get_system_time() - start >= 150'000)
|
else if (get_system_time() - start >= 150'000)
|
||||||
{
|
{
|
||||||
|
std::this_thread::sleep_for(1ms);
|
||||||
passed_count++;
|
passed_count++;
|
||||||
start = 0;
|
start = 0;
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1636,37 +1645,29 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
|
||||||
if (!spu_list)
|
if (!spu_list)
|
||||||
{
|
{
|
||||||
// Give up for now
|
// Give up for now
|
||||||
std::this_thread::sleep_for(10ms);
|
std::this_thread::sleep_for(50ms);
|
||||||
passed_count++;
|
passed_count++;
|
||||||
start = 0;
|
start = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid using suspend_all when more than 2 threads known to be unsavable
|
// Avoid using suspend_all when more than 2 threads known to be unsavable
|
||||||
u32 unsavable_threads = 0;
|
u32 savable_threads = 0;
|
||||||
|
|
||||||
for (auto& spu : *spu_list)
|
for (auto& spu : *spu_list)
|
||||||
{
|
{
|
||||||
if (spu->unsavable)
|
if (!spu->unsavable)
|
||||||
{
|
{
|
||||||
unsavable_threads++;
|
savable_threads++;
|
||||||
|
|
||||||
if (unsavable_threads >= 3)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unsavable_threads >= 3)
|
if (!savable_threads)
|
||||||
{
|
{
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flag for optimization
|
|
||||||
bool paused_anyone = false;
|
|
||||||
|
|
||||||
if (cpu_thread::suspend_all(nullptr, {}, [&]()
|
if (cpu_thread::suspend_all(nullptr, {}, [&]()
|
||||||
{
|
{
|
||||||
if (!get_spus(false, true))
|
if (!get_spus(false, true))
|
||||||
|
|
@ -1695,19 +1696,13 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
paused_anyone = true;
|
|
||||||
ensure(!spu->state.test_and_set(cpu_flag::dbg_global_pause));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (failed && paused_anyone)
|
|
||||||
{
|
|
||||||
// For faster signalling, first remove state flags then batch notifications
|
|
||||||
for (auto& spu : *spu_list)
|
for (auto& spu : *spu_list)
|
||||||
{
|
{
|
||||||
spu->state -= cpu_flag::dbg_global_pause;
|
if (!failed && !is_emu_paused)
|
||||||
|
{
|
||||||
|
ensure(!spu->state.test_and_set(cpu_flag::dbg_global_pause));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1719,13 +1714,6 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!paused_anyone)
|
|
||||||
{
|
|
||||||
// Need not do anything
|
|
||||||
std::this_thread::yield();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& spu : *spu_list)
|
for (auto& spu : *spu_list)
|
||||||
{
|
{
|
||||||
if (spu->state & cpu_flag::wait)
|
if (spu->state & cpu_flag::wait)
|
||||||
|
|
@ -1755,7 +1743,7 @@ extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool reve
|
||||||
{
|
{
|
||||||
spu->state.notify_one();
|
spu->state.notify_one();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue