Skip to content

performance.timeOrigin set incorrectly #17893

Closed
@TimothyGu

Description

@TimothyGu
  • Version: v9.x / master
  • Platform: all
  • Subsystem: perf_hooks
$ ./node -p 'new Date(perf_hooks.performance.timeOrigin).toString()'
Sat Jan 03 1970 08:35:02 GMT+0800 (CST)

while in browsers

> new Date(performance.timeOrigin).toString()
"Thu Dec 28 2017 15:02:33 GMT+0800 (CST)"

performance.timeOrigin is spec'd to return the time origin timestamp, which is a high-resolution UNIX time, rather than a time from an arbitrary position in the past (what it currently returns).

Unfortunately, after looking over the libuv documentation I could not find a function that returns something akin to clock_gettime(CLOCK_REALTIME, tp) on POSIX systems. The ideal solution is, of course, adding such a method to libuv. But if it is not possible to do so in a timely manner, I did outline a hack that allows me to get the correct high-precision value of timeOrigin in jsdom/jsdom#2094 (comment), reproduced below:

const { timeOrigin } = process.binding(...);

// Currently:
// performance.timeOrigin = timeOrigin;

// Offset between the time returned by process.hrtime() and Date.now(). A.k.a. the |t1|
// in W3C [HR-TIME] spec.
const hrtimeOffset = getHrtimeOffset();

const timeOriginTimestamp = hrtimeOffset + timeOrigin;
performance.timeOrigin = timeOriginTimestamp;

function getHrtimeOffset() {
  // Wait at most 1 millisecond, a negligible amount of time for initialization.
  let cur = Date.now();
  const next = cur + 1;
  while (cur !== next) {
    cur = Date.now();
  }

  // At this point cur "just" became equal to the next millisecond -- the unseen digits after cur
  // are approximately all 0, and cur is the closest to the actual value of the UNIX time.
  // Now, get the current global monotonic clock value:

  const [hrSec, hrNS] = process.hrtime();
  const globalMonotonicClockMS = hrSec * 1e3 + hrNS / 1e6;

  // Let |t1| be the DOMHighResTimeStamp representing the high resolution Unix time at
  // which the global monotonic clock is zero.
  // I.e., t1 + globalMonotonicClockMS = cur
  //       t1                          = cur - globalMonotonicClockMS
  return cur - globalMonotonicClockMS;
}

but it requires at most 1ms of initialization time when perf_hooks is required.

Thoughts?

/cc @bnoordhuis @cjihrig @jasnell

Metadata

Metadata

Assignees

Labels

perf_hooksIssues and PRs related to the implementation of the Performance Timing API.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions