Skip to content

Fix mainThreadBusy intermittent failures in event-timing tests due to timer precision rounding #1247

@canova

Description

@canova

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    test-change-proposalProposal to add or remove tests for an interop area

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions