-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sys_game_watchdog minor fixups #12827
Conversation
5147c91
to
a6eb829
Compare
d05bd2d
to
3b0637a
Compare
rpcs3/Emu/Cell/lv2/sys_game.cpp
Outdated
{ | ||
if (Emu.IsStopped() || get_timestamp() - watchdog_last_clear > timeout * 1000000) | ||
if (Emu.IsPaused()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't we just use get_system_time() - Emu.GetPauseTime()
to offset the paused time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rather the time be observed by the thread itself, GetPauseTime has a theoretical thread safety issue because Emu.Pause() does not wait for all threads to actually pause.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see.
auto watchdog = [=]() | ||
{ | ||
while (!watchdog_stopped) | ||
constexpr u64 sleep_time = 50'000; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder how this is decided.
In the log, I saw the watchdog was cleared each frame (sys_game_watchdog_clear() was called per 16.x ms).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this API has 1s resolution anyway, why it matters?
77ca8d1
to
b848c11
Compare
} | ||
}; | ||
|
||
error_code _sys_game_watchdog_start(u32 timeout) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you help me confirm if the param 1 is indeed u32?
I was unable to check as in Ghidra it was shown as undefined
, and the psdevwiki just said it's int time(r)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I've checked,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind sending me the disassembly of sys_game syscalls so that I might be able to implement them more accurately in the future? Thank you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IDA file. lv2_446_+_bss_data.zip
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you.
f49dc89
to
6d48e15
Compare
rpcs3/Emu/Cell/lv2/sys_game.cpp
Outdated
{ | ||
bool needs_restart = false; | ||
bool active = false; | ||
char pad[sizeof(u64) - sizeof(bool) * 2]{}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where's this (char pad[]) used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's so atomic compare&swap operations have defined result because they may fail with implicit padding bytes in some cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it.
I'll test it with the actual game later. |
rpcs3/Emu/Cell/lv2/sys_game.cpp
Outdated
{ | ||
if (Emu.IsStopped() || get_timestamp() - watchdog_last_clear > timeout * 1000000) | ||
if (Emu.IsPaused()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The watchdog wasn't triggered when the game status was "frozen" because Emu.IsPaused() includes not only paused
, but also frozen
, ready
, and starting
. Shouldn't the watchdog attempt to restart the game when the game is no longer responding?
The watchdog worked well when the game intentionally stopped calling sys_game_watchdog_clear()
(but the game wasn't actually frozen).
However, the watchdog wasn't triggered when the game was frozen unexpectedly (F {PPU[0x1000000] Thread (main_thread) [0x005130c8]} VM: Access violation reading location 0x0 (unmapped memory)
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I need to think what to do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great. It was triggered in both cases.
Thank you for your hard work!
@elad335 By the way, is it safe to remove the implemented sys_game syscalls from /Emu/Cell/Modules/sys_game_.cpp? |
No because they are not syscalls. |
Requesting @brian218 to review.