-
Notifications
You must be signed in to change notification settings - Fork 33
Description
Test List
More of a test util function (mainThreadBusy) used by multiple tests: event-timing/resources/event-timing-test-utils.js
Main test that's affected by this is: event-timing/duration-with-target-low.html
Rationale
Currently event timing tests have the mainThreadBusy function, which is used to block the main thread for a specific duration. It's used by a lot of tests.
We were investigating some intermittent timeouts/failures in Firefox (in bug 2011967) and realized that some tests were actually waiting less than the provided duration.
The issue is that mainThreadBusy relies on performance.now() for timing, but Firefox rounds these timestamps to 1ms precision for privacy protection against timing attacks (e.g., Spectre). When the test requests a 300ms busy-wait (for example in event-timing/duration-with-target-low.html), the loop can exit early (~299ms) when timestamps round unfavorably. For example, if the start timestamp rounds down and the end timestamp rounds up as well, we might get only 299ms of actual blocking time.
This causes intermittent failures because the busy-wait duration doesn't consistently meet the required threshold. We observed about a 10% failure rate in affected tests.
Proposed Fix
We propose adding a 2ms overshoot to the mainThreadBusy function to account for timer precision rounding and jitter (example commit):
function mainThreadBusy(ms) {
const target = performance.now() + ms + 2;
while (performance.now() < target);
}The 2ms buffer ensures that even with unfavorable rounding, the function will block for at least the requested duration across all browsers.
1ms would be sufficient to account for timer precision rounding alone, but we use 2ms for good measure to also allow for any possible similar issues from "jitter" (intentional anti-fingerprinting randomness introduced into performance.now() values, which may make them lie by up to 1ms, while still keeping them monotonically increasing).
This change is conservative and doesn't negatively impact test behavior. I tested the change in both Chrome and Safari, and they continue to pass all tests with this modification, and it eliminates the intermittent failures we were seeing in Firefox.
PR that implements the proposal is in web-platform-tests/wpt#57314.