cellGem: Use wait_on, fix fake/mouse move tracker wait

This commit is contained in:
Megamouse 2025-01-08 19:08:21 +01:00
parent 3b8efecc52
commit 3eb1e6303c

View file

@ -289,20 +289,21 @@ public:
m_done.notify_one(); m_done.notify_one();
} }
void wait_for_result() bool wait_for_result(ppu_thread& ppu)
{ {
if (!m_done) while (!m_done && !ppu.is_stopped())
{ {
m_done.wait(0); thread_ctrl::wait_on(m_done, 0);
m_done = 0;
} }
}
gem_config_data& operator=(thread_state) if (ppu.is_stopped())
{ {
wake_up(); ppu.state += cpu_flag::again;
done(); return false;
return *this; }
m_done = 0;
return true;
} }
// helper functions // helper functions
@ -1253,7 +1254,7 @@ void gem_config_data::operator()()
while (thread_ctrl::state() != thread_state::aborting && !Emu.IsStopped()) while (thread_ctrl::state() != thread_state::aborting && !Emu.IsStopped())
{ {
atomic_wait_timeout timeout = atomic_wait_timeout::inf; u64 timeout = umax;
if (state && !video_conversion_in_progress) if (state && !video_conversion_in_progress)
{ {
@ -1263,11 +1264,11 @@ void gem_config_data::operator()()
if (elapsed_us < update_timeout_us) if (elapsed_us < update_timeout_us)
{ {
timeout = atomic_wait_timeout{(update_timeout_us - elapsed_us) * 1000}; timeout = update_timeout_us - elapsed_us;
} }
else else
{ {
timeout = atomic_wait_timeout{update_timeout_us * 1000}; timeout = update_timeout_us;
last_update_us = now_us; last_update_us = now_us;
std::scoped_lock lock(mtx); std::scoped_lock lock(mtx);
@ -1278,7 +1279,7 @@ void gem_config_data::operator()()
if (!m_wake_up) if (!m_wake_up)
{ {
m_wake_up.wait(0, timeout); thread_ctrl::wait_on(m_wake_up, 0, timeout);
} }
m_wake_up = 0; m_wake_up = 0;
@ -1337,25 +1338,39 @@ public:
return m_busy; return m_busy;
} }
void wake_up() void wake_up_tracker()
{ {
m_wake_up.release(1); m_wake_up_tracker.release(1);
m_wake_up.notify_one(); m_wake_up_tracker.notify_one();
} }
void done() void tracker_done()
{ {
m_done.release(1); m_tracker_done.release(1);
m_done.notify_one(); m_tracker_done.notify_one();
} }
void wait_for_result() bool wait_for_tracker_result(ppu_thread& ppu)
{ {
if (!m_done) if (g_cfg.io.move != move_handler::real)
{ {
m_done.wait(0); m_tracker_done = 0;
m_done = 0; return true;
} }
while (!m_tracker_done && !ppu.is_stopped())
{
thread_ctrl::wait_on(m_tracker_done, 0);
}
if (ppu.is_stopped())
{
ppu.state += cpu_flag::again;
return false;
}
m_tracker_done = 0;
return true;
} }
bool set_image(u32 addr) bool set_image(u32 addr)
@ -1410,13 +1425,6 @@ public:
return ::at32(m_info, gem_num); return ::at32(m_info, gem_num);
} }
gem_tracker& operator=(thread_state)
{
wake_up();
done();
return *this;
}
void operator()() void operator()()
{ {
if (g_cfg.io.move != move_handler::real) if (g_cfg.io.move != move_handler::real)
@ -1434,10 +1442,10 @@ public:
while (thread_ctrl::state() != thread_state::aborting) while (thread_ctrl::state() != thread_state::aborting)
{ {
// Check if we have a new frame // Check if we have a new frame
if (!m_wake_up) if (!m_wake_up_tracker)
{ {
m_wake_up.wait(0); thread_ctrl::wait_on(m_wake_up_tracker, 0);
m_wake_up.release(0); m_wake_up_tracker.release(0);
if (thread_ctrl::state() == thread_state::aborting) if (thread_ctrl::state() == thread_state::aborting)
{ {
@ -1523,7 +1531,7 @@ public:
} }
// Notify that we are finished with this frame // Notify that we are finished with this frame
done(); tracker_done();
m_busy.release(false); m_busy.release(false);
} }
@ -1534,8 +1542,8 @@ public:
shared_mutex mutex; shared_mutex mutex;
private: private:
atomic_t<u32> m_wake_up = 0; atomic_t<u32> m_wake_up_tracker = 0;
atomic_t<u32> m_done = 1; atomic_t<u32> m_tracker_done = 1;
atomic_t<bool> m_busy = false; atomic_t<bool> m_busy = false;
ps_move_tracker<false> m_tracker{}; ps_move_tracker<false> m_tracker{};
CellCameraInfoEx m_camera_info{}; CellCameraInfoEx m_camera_info{};
@ -2226,7 +2234,7 @@ error_code cellGemClearStatusFlags(u32 gem_num, u64 mask)
return CELL_OK; return CELL_OK;
} }
error_code cellGemConvertVideoFinish() error_code cellGemConvertVideoFinish(ppu_thread& ppu)
{ {
cellGem.warning("cellGemConvertVideoFinish()"); cellGem.warning("cellGemConvertVideoFinish()");
@ -2242,7 +2250,10 @@ error_code cellGemConvertVideoFinish()
return CELL_GEM_ERROR_CONVERT_NOT_STARTED; return CELL_GEM_ERROR_CONVERT_NOT_STARTED;
} }
gem.wait_for_result(); if (!gem.wait_for_result(ppu))
{
return {};
}
return CELL_OK; return CELL_OK;
} }
@ -2417,7 +2428,10 @@ error_code cellGemEnd(ppu_thread& ppu)
} }
auto& tracker = g_fxo->get<named_thread<gem_tracker>>(); auto& tracker = g_fxo->get<named_thread<gem_tracker>>();
tracker.wait_for_result(); if (!tracker.wait_for_tracker_result(ppu))
{
return {};
}
gem.updating = false; gem.updating = false;
@ -3507,7 +3521,7 @@ error_code cellGemTrackHues(vm::cptr<u32> req_hues, vm::ptr<u32> res_hues)
return CELL_OK; return CELL_OK;
} }
error_code cellGemUpdateFinish() error_code cellGemUpdateFinish(ppu_thread& ppu)
{ {
cellGem.warning("cellGemUpdateFinish()"); cellGem.warning("cellGemUpdateFinish()");
@ -3526,7 +3540,10 @@ error_code cellGemUpdateFinish()
} }
auto& tracker = g_fxo->get<named_thread<gem_tracker>>(); auto& tracker = g_fxo->get<named_thread<gem_tracker>>();
tracker.wait_for_result(); if (!tracker.wait_for_tracker_result(ppu))
{
return {};
}
gem.updating = false; gem.updating = false;
@ -3576,7 +3593,7 @@ error_code cellGemUpdateStart(vm::cptr<void> camera_frame, u64 timestamp)
return not_an_error(CELL_GEM_NO_VIDEO); return not_an_error(CELL_GEM_NO_VIDEO);
} }
tracker.wake_up(); tracker.wake_up_tracker();
return CELL_OK; return CELL_OK;
} }