Skip to content

Commit 2a46345

Browse files
committed
Improve & simplify time sync in pthreads
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.
1 parent 15bf099 commit 2a46345

File tree

3 files changed

+5
-19
lines changed

3 files changed

+5
-19
lines changed

src/library.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,12 +2328,10 @@ mergeInto(LibraryManager.library, {
23282328
"} else " +
23292329
#endif
23302330
#if USE_PTHREADS
2331-
// Pthreads need their clocks synchronized to the execution of the main thread, so give them a special form of the function.
2332-
// N.b. Wasm workers do not provide this kind of clock synchronization.
2333-
"if (ENVIRONMENT_IS_PTHREAD) {\n" +
2334-
" _emscripten_get_now = () => performance.now() - Module['__performance_now_clock_drift'];\n" +
2335-
"} else " +
2336-
#endif
2331+
// Pthreads need their clocks synchronized to the execution of the main thread, so, when using them,
2332+
// make sure to adjust all timings to the respective time origins.
2333+
"_emscripten_get_now = () => performance.timeOrigin + performance.now();\n",
2334+
#else
23372335
#if ENVIRONMENT_MAY_BE_SHELL
23382336
"if (typeof dateNow != 'undefined') {\n" +
23392337
" _emscripten_get_now = dateNow;\n" +
@@ -2349,6 +2347,7 @@ mergeInto(LibraryManager.library, {
23492347
// Modern environment where performance.now() is supported:
23502348
// N.B. a shorter form "_emscripten_get_now = return performance.now;" is unfortunately not allowed even in current browsers (e.g. FF Nightly 75).
23512349
"_emscripten_get_now = () => performance.now();\n",
2350+
#endif
23522351
#endif
23532352

23542353
emscripten_get_now_res: function() { // return resolution of get_now, in nanoseconds

src/library_pthread.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,6 @@ var LibraryPThread = {
607607
worker.ref();
608608
}
609609
#endif
610-
msg.time = performance.now();
611610
worker.postMessage(msg, threadParams.transferList);
612611
delete worker.runPthread;
613612
};

src/worker.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -205,18 +205,6 @@ self.onmessage = (e) => {
205205
#endif
206206
#endif // MODULARIZE && EXPORT_ES6
207207
} else if (e.data.cmd === 'run') {
208-
// This worker was idle, and now should start executing its pthread entry
209-
// point.
210-
// performance.now() is specced to return a wallclock time in msecs since
211-
// that Web Worker/main thread launched. However for pthreads this can
212-
// cause subtle problems in emscripten_get_now() as this essentially
213-
// would measure time from pthread_create(), meaning that the clocks
214-
// between each threads would be wildly out of sync. Therefore sync all
215-
// pthreads to the clock on the main browser thread, so that different
216-
// threads see a somewhat coherent clock across each of them
217-
// (+/- 0.1msecs in testing).
218-
Module['__performance_now_clock_drift'] = performance.now() - e.data.time;
219-
220208
// Pass the thread address to wasm to store it for fast access.
221209
Module['__emscripten_thread_init'](e.data.pthread_ptr, /*isMainBrowserThread=*/0, /*isMainRuntimeThread=*/0, /*canBlock=*/1);
222210

0 commit comments

Comments
 (0)