Skip to content

hrtime() is not monotonic — second reading can be smaller than the first #23443

Description

@PurHur

hrtime() returns values that go backwards, so a monotonicity check fails intermittently. This makes stdlib/hrtime_named flaky in both VMTest and JITTest (sampled 12 runs: 7/12 pass).

Repro:

<?php
$a = hrtime(as_number: true);
$b = hrtime(as_number: true);
var_dump($a, $b, $b >= $a);
phpc VM:  int(3202530260000706)  int(3202530259999766)  bool(false)
Zend:     int(3202532083354630)  int(3202532083359539)  bool(true)

Two things are wrong:

  • the second reading is smaller than the first — CLOCK_MONOTONIC cannot go backwards, so the value is not coming from a monotonic source (or is being reassembled from sec/nsec parts incorrectly);
  • the trailing digits are quantised — …260000706, …259999766, …260000659 — the low-order nanoseconds look synthesised rather than read, whereas Zend's vary freely.

Both suggest the sec and nsec components are being combined wrongly (e.g. nsec taken from a different sample than sec, or a rounded/scaled value), rather than a resolution limitation.

Present on master; unrelated to #23354, found while verifying its regression list. Affects stdlib/hrtime, stdlib/hrtime_named, stdlib/hrtime_native, stdlib/hrtime_jit_vm, which flip between pass and fail across runs and make regression comparisons noisy.

Done when: two consecutive hrtime(as_number: true) calls never decrease, and the low-order digits vary as they do under Zend.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions