Skip to content
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

Stability fixes #12496

Merged
merged 2 commits into from
Aug 11, 2022
Merged

Stability fixes #12496

merged 2 commits into from
Aug 11, 2022

Conversation

elad335
Copy link
Contributor

@elad335 elad335 commented Aug 11, 2022

Adds 2 new bug fixes. (not regression fixes)

  • Fix an LV2 bug that over time can randomly kill the PPUs at once. Timeline of the race condition:

  1. The PPU is in SLEEP state. state = suspend.
  2. lv2_obj::awake is called on the traced thread and is now in ONPROC state, state = signal.
  3. lv2_obj::awake is called by another thread externally with a priority higher than our traced thread and appends it to g_pending. state = suspend + signal.
  4. lv2_obj::sleep/set_priority (highering priority) is called on any thread which is in ONPROC. Causing it to enter SLEEP or RUNNING state, while the traced thread is back in queue in ONPROC. state = suspend + signal.
  5. The traced thread finally calls lv2_obj::awake on itself, g_pending decrements to 0 and we a have a rescheduling event, after XOR state = no flags (no signal)
  6. In cpu_thread::check_state: cpu_sleep_called is now true and remains this way.
  7. Another thread with a higher prioty kicks in and appends the traced thread into g_pending. state = suspend.
  8. The traced thread is at cpu_thread::cpu_wait() waiting on state flags, awake is not called again because cpu_sleep_called is true. And that function is where it's gonna spend the rest of its life.
    Fix this bug by not using XOR, instead properly add signal and substruct suspend flags.
  • Fix a loose notification in lwcond wait: put awake under mutex lock so when an lwmutex waiter times out a notification won't be able to awake it from other syscalls.

For me it fixes freezes in Demon Souls after a while, but its effect is global on games some may experience the freeze much earlier than others.

Timeline of the race:
1. The PPU is in SLEEP state. state = suspend.
2. lv2_obj::awake is called on the traced thread and is now in ONPROC state, state = signal.
3. lv2_obj::awake is called by another thread externally with a priority higher than our traced thread and appends it to g_pending. state = suspend + signal.
4. lv2_obj::sleep/set_priority (higering priority) is called on any thread which is in ONPROC. Causing it to enter SLEEP or RUNNING state, while the traced thread is back in queue in ONPROC. state = suspend + signal.
5. The traced thread finally calls lv2_obj::awake on itself, g_pending decrements to 0 and we a have a rescheduling event, after XOR state = 0!!! (no signal)
6. In check_state: cpu_sleep_called is now true and remains this way.
7. Another thread with a higher prioty kicks in and appends the traced thread into g_pending. state = suspend.
8. The traced thread is at cpu_thread::cpu_wait(), and that's where it's gonna spend the rest of its life.
@Nekotekina Nekotekina merged commit 7ff4509 into RPCS3:master Aug 11, 2022
@elad335 elad335 deleted the stability-fixes branch August 11, 2022 09:50
@Nerboruto
Copy link

possible that after all these fixes demon souls run well even with only one thread ppu? before it crashed, without recompiling cache.
tested on intel quad core cpu, performances seem identical indeed perhaps even a bit more fluid.

@elad335
Copy link
Contributor Author

elad335 commented Aug 11, 2022

Why would you run on a single PPU? PPU thread count is not a "performance hint", it has real consequences on game compatibility. Lots of games aren't compatible with 1 PPU thread and they will never be.

@Nerboruto
Copy link

Nerboruto commented Aug 11, 2022

yes I tried others and they crash ... I did the test because I saw that by limiting the spu threads to 3 the game runs better on quad core and so I wanted to try the ppu too ... anyway I remember first that ds crashed and I repeat it seems more fluid with 1 ppu.

other tricks that I have tried and improve the performance are patches to 60 but vblanlk to 30. much smoother than the default 30 and decompress the archives but compress the iso. maybe so I shift the compression load out of the emulator ..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants