Fix macOS InstanceStorage upload wait hang in Gothic2Notr#943
Draft
Crissorl wants to merge 1 commit into
Draft
Conversation
Owner
|
Hi, @Crissorl and thanks for pr! Lets take it into 2 parts:
OK (maybe 2 conditional variables then), but symptoms are strange. Nither main-thread or |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This fixes a reproducible macOS hang seen with
Gothic2Notr/ Gothic II: Night of the Raven by replacing the busy-wait inInstanceStorage::join()with a condition-variable wait, and by notifying the waiting render thread when the upload thread finishes a frame upload.The reproduction was done with Gothic II: Night of the Raven data. The changed
InstanceStoragepath is part of the shared renderer, so this is not intentionally Gothic II script/content-specific.The patch also changes
Cpu32::popString()to return an emptystd::stringinstead of0for an empty stack, which is required for a clean build with the current macOS clang/libc++ toolchain.Root cause
On macOS arm64, the app could become unresponsive while rendering. A spindump taken during the hang showed the main thread stuck in:
MainWindow::render() -> Renderer::draw() -> InstanceStorage::join()The old implementation repeatedly acquired and released
syncuntiluploadFId < 0. At the same time, the upload worker could wait onuploadCndwithout a predicate and did not notify after settinguploadFId = -1. In practice this could leave the main render path spinning around the mutex while the app was already marked "Application Not Responding" by macOS.This patch makes both sides use explicit condition predicates:
join()sleeps untiluploadFId < 0uploadMain()sleeps until upload work is availableuploadMain()notifies after completing the upload and resettinguploadFIdReproduction details
Observed with the macOS arm64
Gothic2Notrrelease build using Gothic II: Night of the Raven data on:Gothic2Notrbuild based on the current releaseSymptoms:
InstanceStorage::join()After applying this patch, the same Gothic II: Night of the Raven save/load path ran without the recurring freeze during manual gameplay testing on the same machine. I did not observe further hangs or crashes during the remaining play session, and the game was noticeably more stable on this Mac.
Validation
cmake --build build-ko --target Gothic2Notr -j 8