Open Bug 1429926 Opened 6 years ago Updated 1 year ago

performance.timeOrigin + performance.now() is waaay off in one content process, not another

Categories

(Core :: DOM: Performance, defect, P2)

59 Branch
Unspecified
macOS
defect

Tracking

()

Tracking Status
firefox59 --- affected

People

(Reporter: jib, Unassigned, NeedInfo)

References

(Blocks 1 open bug)

Details

STRs:
 1. On my MBP, in a Nightly instance that's been open for a good bit (maybe even before I opened the lid),
 2. I open https://jsfiddle.net/jib1/t1vmjvvw/ in two different-process tabs (check tab tooltip process id)

Expected result:
  Reasonably similar values in both tabs.

Actual result:

In Tab A (pid 818):

  date: 1515708419097, nperf: 1515708419097.38, diff: -0.3798828125
  date: 1515708419097, tperf: 1515708417677.28, diff: 1419.719970703125

In Tab B (pid 819) (Took me about a second to hit Run in both):

  date: 1515708421003, nperf: 1515708421002.64, diff: 0.360107421875
  date: 1515708421003, tperf: 1515704710256.94, diff: 3710746.0600585938

where

  nperf is performance.timing.navigationStart + performance.now()
  tperf is performance.timeOrigin + performance.now()
  diff is how well they track Date.now()

As you can see, the timeOrigin in Tab B is off by a good hour. A few days ago, I saw it off by 14 hours.

FWIW bz on irc mentioned a theory about my machine having been in sleep mode possibly being a culprit.
> Reasonably similar values in both tabs.

Why?  timeOrigin is stored per-process right now.  If you start a new process, it will exactly match Unix time at the very first.  After that it can diverge if the monotonic and wall-clock clocks don't tick at the same rate.

My theory is that our monotonic clock does not tick during sleep, on at least some OSes.  Which OS are you on?
Blocks: 1430255
No longer depends on: 1430255
(In reply to Boris Zbarsky [:bz] (no decent commit message means r-) from comment #1)
> > Reasonably similar values in both tabs.
> 
> Why?  timeOrigin is stored per-process right now.

I'd expect performance.timeOrigin + performance.now() to match across processes [1] even if timeOrigin is different.

Our interest is that we may pref off the new getContributingSources() and getContributingSources() APIs in 59, over two issues:

 1. audioLevel (unrelated) https://github.com/w3c/webrtc-pc/issues/1734
 2. timestamp (related) https://github.com/w3c/webrtc-pc/issues/1690#issuecomment-356980280

The second is about using the proper clock. The important bit is letting people do timestamp math against the right clock:

    let now = performance.timeOrigin + performance.now();
    let lastSsrc = getSynchronizationSources()[0].timestamp;
    let ssrcAge = now - lastSsrc;

and we'd want to fix stats timestamp at the same time:

    let older = [...(await getStats()).values()].filter(stat => stat.timestamp < lastSsrc)

I guess in theory it won't matter if timeOrigin is off by 14 hours, it'll just be a bit embarrassing if people log it to console [2]:

    console.log(new Date(lastSsrc).toTimeString());
    older.forEach(stat => console.log(new Date(stat.timestamp).toTimeString());

> My theory is that our monotonic clock does not tick during sleep, on at
> least some OSes.  Which OS are you on?

OSX 10.12.6 (16G29)

[1] https://mozilla.logbot.info/content/20180111#c14118411
[2] https://jsfiddle.net/jib1/6j072zcx/
Summary: performance.timeOrigin is waaay off in one content process, not another → performance.timeOrigin is waaay off! (in one content process, not another)
Summary: performance.timeOrigin is waaay off! (in one content process, not another) → performance.timeOrigin + performance.now() is waaay off in one content process, not another
> I'd expect performance.timeOrigin + performance.now() to match across processes

Do we do BroadcastChannel across processes?  https://www.w3.org/TR/hr-time-2/#dfn-global-monotonic-clock explicitly says that there can be separate "global monotonic clocks" around as long as they can't communicate with each other; the only question is what the right granularity is.

In Gecko, the granularity is per-process right now, because we just have a separate copy of PerformanceService per process.  If this is not the right granularity, then we should fix that, I agree.

> new Date(stat.timestamp)

There's no guarantee that will do anything useful, obviously, if stat.timestamp comes from a monotonic clock...

> OSX 10.12.6 (16G29)

OK, I am also on OSX.  On Mac, our monotonic clock uses mach_absolute_time.  Looks to me based on http://www.cocoabuilder.com/archive/cocoa/291099-elapsed-time-vs-sleep.html and https://stackoverflow.com/questions/19817867/clock-get-time-mach-absolute-time-stops-updating-when-device-goes-to-sleep-on-io/19844197#19844197 and so forth that it in fact does not increment during sleep.
Priority: -- → P2
Component: DOM → DOM: Core & HTML

Hey Jan,
Can you still reproduce this or should we close it?
I can't see any differences between my values rather than 1, 0 or 2 over a period of 4-5 hours of rolling the tests on MacOS 11.6.

Flags: needinfo?(jib)

In the process of migrating remaining bugs to the new severity system, the severity for this bug cannot be automatically determined. Please retriage this bug using the new severity system.

Severity: major → --
Component: DOM: Core & HTML → DOM: Performance
You need to log in before you can comment on or make changes to this bug.