-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Add some test coverage for threads+OFFSCREEN_FRAMEBUFFER+MAIN_MODULE=1. NFC #25449
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
Conversation
Remarkably, the new test combination added in this PR fails consistently in Firefox, except for Firefox Nightly: ![]() The reason for this is that We have a polyfill for Atomics.waitAsync in emscripten/src/lib/libatomic.js Lines 10 to 70 in 7125c45
|
Oh man, that could be a pain to debug. I guess the polyfill must be in use a in a lot of places in Firefox already though right? Basically all pthread tests depend on this right? So it must be some strange edge case that is being hit here, in code that works most of the time? |
It will have to be a very specific condition when the Atomics.waitAsync() wait comes into play. It is not used in general: I never added an use of it into our system libraries that I could remember. (because I considered it to be just broken and misdesigned at the time) I vaguely recall reading through @tlively 's mailbox/proxying queue impl. that maybe it might have had an use, but can't find one now either. |
Yes, its used in |
I guess it only happens when pthreads exit to their event loop, which might be be too common? |
The code didn't take into about that system_libs could also contains flags such as `--whole-archive`. In this particular test the value of `system_libs` is: ``` ['-lGL-getprocaddr', '-lal', '-lhtml5', '-lstubs-debug', '-lc-debug', '-ldlmalloc-debug', '-lcompiler_rt', '--whole-archive', '-lc++-debug-noexcept', '--no-whole-archive', '-lc++abi-debug-noexcept', '-lsockets', '--whole-archive', '-llsan_rt', '--no-whole-archive', '-llsan_common_rt', '-lsanitizer_common_rt'] ```
The code didn't take into about that system_libs could also contains flags such as `--whole-archive`. In this particular test the value of `system_libs` is: ``` ['-lGL-getprocaddr', '-lal', '-lhtml5', '-lstubs-debug', '-lc-debug', '-ldlmalloc-debug', '-lcompiler_rt', '--whole-archive', '-lc++-debug-noexcept', '--no-whole-archive', '-lc++abi-debug-noexcept', '-lsockets', '--whole-archive', '-llsan_rt', '--no-whole-archive', '-llsan_common_rt', '-lsanitizer_common_rt'] ```
This failure was causing the emscripten-reeleases roller to fail. The code didn't take into about that system_libs could also contains flags such as `--whole-archive`. In this particular test the value of `system_libs` is: ``` ['-lGL-getprocaddr', '-lal', '-lhtml5', '-lstubs-debug', '-lc-debug', '-ldlmalloc-debug', '-lcompiler_rt', '--whole-archive', '-lc++-debug-noexcept', '--no-whole-archive', '-lc++abi-debug-noexcept', '-lsockets', '--whole-archive', '-llsan_rt', '--no-whole-archive', '-llsan_common_rt', '-lsanitizer_common_rt'] ``` Fixes: #25472
The polyfill is always being injected if the target browser does not support Atomics.waitAsync(). The issue is that in order to be 100% correct, it is not possible to polyfill Atomics.waitAsync() without also monkey-patching Atomics.notify(), to provide a separate channel for notifying the emulated waitAsync() waiters. To avoid that issue, I implemented the polyfill waitAsync() as a setTimeout() loop that polls the waitAsync() target memory location, and notifies waitAsync() when the memory location changes value. This matches the idea of futex wait "sleep this thread as long as this memory location has its current value X." And it works as long as the notifier will change the value of the memory location before notifying. That is the pattern that is used when implementing the common mutexes/semaphores/barries etc. Reading the way that atomics.wait/.notify is being used by the mailbox implementation, it seems that it uses futex sleep/wake as a signal. When the wakeup notification is done, the memory location value is not changed, but the location is just notified. The polyfill waitAsync() cannot detect this as being a notification, so it never wakes up the waitAsync() waiter. In general notifying without first changing the value is racy when locks/semaphores/barriers are concerned - changing the value helps implement the atomicity needed in the sleep+wakeup., But this is probably not an issue in the mailbox implementation. To resolve this problem, three possible ways: remove the waitAsync polyfill, or restrict the polyfill to not cover the mailbox (essentially mailbox has its own polyfill), or change the mailbox impl. to also change the memory location value before waking up the waiter. |
…polyfill over the usage pattern in Emscripten mailbox implementation. See emscripten-core#25449 (comment) . The mailbox implementation has its own postMessage() fallback, so does not need the polyfill. Fixes test browser.test_gl_textures_pthreads_main_module in Firefox."
Delete the Atomics.waitAsync() polyfill, which is not good enough to polyfill over the usage pattern in Emscripten mailbox implementation. See #25449 (comment) . The mailbox implementation has its own postMessage() fallback, so does not need the polyfill. Fixes test browser.test_gl_textures_pthreads_main_module in Firefox." This will be a breaking change to any users who successfully depended on the polyfill (i.e. only needed the partial support it brought), though it is uncertain if there are any. Fixes test `browser.test_gl_textures_pthreads_main_module` on Firefox.
See #19046