-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Fix relative time in pthreads [v2] #10137
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
Thank you for submitting a pull request! If this is your first PR, make sure to add yourself to AUTHORS. |
Looking at the changes, agree that the relative clock skew computation was broken after the move from global state to Module-specific state. What strikes me curious is there is already a test for this skew in # Test that emscripten_get_now() reports coherent wallclock times across all pthreads, instead of each pthread independently reporting wallclock times since the launch of that pthread.
@requires_threads
def test_pthread_clock_drift(self):
self.btest(path_from_root('tests', 'pthread', 'test_pthread_clock_drift.cpp'), expected='1', args=['-O3', '-s', 'USE_PTHREADS=1', '-s', 'PROXY_TO_PTHREAD=1']) I wonder why that test would pass even when the implementation regressed? |
Curious indeed. A major difference might be that the existing test uses |
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.
Thanks for the help here @niklasf! Looks perfect.
Yes, I think the issue with the old test was that it uses proxy-to-pthread. That avoided the bug somehow (I looked at this back then, but don't remember the details). I did verify that the new test was broken before the fix, and fixed with it.
Pthreads get the current time from their parent thread during startup, so they can return results that make sense relative to it. Without that, the time on a pthread can be "earlier" than the time on the main thread, even if the pthread checks the time later. This broke in emscripten-core#9569 when we removed the magic globals from worker.js, as now such values must be passed explicitly. So that global just had the initial 0 value. The fix is to pass the value on Module and use it from there, safely. This adds a test. Timing tests are always risky, but this just checks monotonicity of the time, and looks 100% consistent when I run it locally, so hopefully it's ok. If we see flakes on CI we may need to remove it though. Fixes emscripten-core#9783 Co-authored-by: Alon Zakai <alonzakai@gmail.com>
This supersedes solution from #6084 / #10137 with `performance.timeOrigin`. This property provides the high resolution baseline for `performance.now()` results, which is exactly what we need. Unlike custom `__performance_now_clock_drift` sent as a message to a worker, it won't suffer from the small time difference incurred by `postMessage` itself, making synchronisation more precise, while at the same time allows to remove some custom code, making it a bit simpler too. I checked caniuse and it's supported in all browsers where SAB are supported, so should be always safe to use when pthreads are enabled. Note that this changes the absolute value returned from emscripten_get_now, but this is fine because that value is already different across engines (e.g. it might already return Date.now() in some browser), and it's explicitly documented as "is only meaningful in comparison to other calls to this function". I verified that test_pthread_reltime still passes too.
This supersedes solution from #6084 / #10137 with `performance.timeOrigin`. This property provides the high resolution baseline for `performance.now()` results, which is exactly what we need. Unlike custom `__performance_now_clock_drift` sent as a message to a worker, it won't suffer from the small time difference incurred by `postMessage` itself, making synchronisation more precise, while at the same time allows to remove some custom code, making it a bit simpler too. I checked caniuse and it's supported in all browsers where SAB are supported, so should be always safe to use when pthreads are enabled. Note that this changes the absolute value returned from emscripten_get_now, but this is fine because that value is already different across engines (e.g. it might already return Date.now() in some browser), and it's explicitly documented as "is only meaningful in comparison to other calls to this function". I verified that test_pthread_reltime still passes too.
This supersedes solution from #6084 / #10137 with `performance.timeOrigin`. This property provides the high resolution baseline for `performance.now()` results, which is exactly what we need. Unlike custom `__performance_now_clock_drift` sent as a message to a worker, it won't suffer from the small time difference incurred by `postMessage` itself, making synchronisation more precise, while at the same time allows to remove some custom code, making it a bit simpler too. I checked caniuse and it's supported in all browsers where SAB are supported, so should be always safe to use when pthreads are enabled. Note that this changes the absolute value returned from emscripten_get_now, but this is fine because that value is already different across engines (e.g. it might already return Date.now() in some browser), and it's explicitly documented as "is only meaningful in comparison to other calls to this function". I verified that test_pthread_reltime still passes too.
This is #9799 + the requested trivial changes and some tweaks. Hope this helps to make progress towards landing the fix.