# Monotonic Time

- Thread: https://externals.io/message/97502
- Original archive: https://news-web.php.net/php.internals/97502
- Started by Niklas Keller on 2017-01-02T23:35:31+00:00
- Messages: 15
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #97502 — Niklas Keller — 2017-01-02T23:35:31+00:00

URL: https://externals.io/message/97502#97502

Morning Internals,

PHP doesn't currently have a way to access a monotonic time. There's a
feature request in the bug tracker: bugs [dot] php [dot] net/
bug.php?id=68029

A monotonic time is required to measure time intervals correctly, e.g. for
implementing event loops based on stream_select. `microtime()` is affected by
NTP and leap seconds and can therefore not be reliably used for measuring
time intervals.

Event loops based on extensions like libuv can take advantage of libuv's
own API for accessing a monotonic time.

Related: twitter [dot] com/danluu/status/815442765811023872
Related: blog [dot] cloudflare [dot] com/how-and-why-the-leap-secon
d-affected-cloudflare-dns/

Node.js does have a monotonic time and calls the function
process.hrtime: nodejs [dot] org/api/process.html#process_p
rocess_hrtime_time

There's an existing PECL extension named hrtime: php [dot] net/manual/
en/book.hrtime.php

I think we can reuse parts of it to implement a function in core to access
a monotonic time, I don't think we need to merge the extension into core.

What do you think about adding such a function to the PHP core?

Regards, Niklas

PS: No links, because stupid PHP.net spam filter ...

---

## #97510 — Niklas Keller — 2017-01-04T12:58:31+00:00

URL: https://externals.io/message/97502#97510 · In reply to: #97502

Resending previous mail, because mail distribution was broken...

Morning Internals,

PHP doesn't currently have a way to access a monotonic time. There's a
feature request in the bug tracker: bugs [dot] php [dot]
net/bug.php?id=68029

A monotonic time is required to measure time intervals correctly, e.g. for
implementing event loops based on stream_select. `microtime()` is affected by
NTP and leap seconds and can therefore not be reliably used for measuring
time intervals.

Event loops based on extensions like libuv can take advantage of libuv's
own API for accessing a monotonic time.

Related: twitter [dot] com/danluu/status/815442765811023872
Related: blog [dot] cloudflare [dot] com/how-and-why-the-leap-secon
d-affected-cloudflare-dns/

Node.js does have a monotonic time and calls the function
process.hrtime: nodejs [dot] org/api/process.html#process_p
rocess_hrtime_time

There's an existing PECL extension named hrtime: php [dot]
net/manual/en/book.hrtime.php

I think we can reuse parts of it to implement a function in core to access
a monotonic time, I don't think we need to merge the extension into core.

What do you think about adding such a function to the PHP core?

Regards, Niklas

PS: No links, because stupid PHP.net spam filter ...

---

## #97514 — Michael Wallner — 2017-01-04T17:00:07+00:00

URL: https://externals.io/message/97502#97514 · In reply to: #97510

> Resending previous mail, because mail distribution was broken...
> 
> Morning Internals,
> 
> PHP doesn't currently have a way to access a monotonic time. There's a
> feature request in the bug tracker: bugs [dot] php [dot]
> net/bug.php?id=68029
> 
> A monotonic time is required to measure time intervals correctly, e.g. for
> implementing event loops based on stream_select. `microtime()` is affected by
> NTP and leap seconds and can therefore not be reliably used for measuring
> time intervals.
> 
...
> There's an existing PECL extension named hrtime: php [dot]
> net/manual/en/book.hrtime.php
> 
> I think we can reuse parts of it to implement a function in core to access
> a monotonic time, I don't think we need to merge the extension into core.
> 
> What do you think about adding such a function to the PHP core?

+1?

Actually, it seems, that hrtime doesn't let you access the current
value, which is, well, quite a major use case, isn't it?


-- 
Regards,
Mike

---

## #97517 — Niklas Keller — 2017-01-05T01:27:19+00:00

URL: https://externals.io/message/97502#97517 · In reply to: #97514

>
> Actually, it seems, that hrtime doesn't let you access the current
> value, which is, well, quite a major use case, isn't it?


Yes, that seemed weird to me, too. Did we miss anything, Anatol?

Regards, Niklas

---

## #97541 — Anatol Belski — 2017-01-06T18:58:02+00:00

URL: https://externals.io/message/97502#97541 · In reply to: #97517

Hi,

> -----Original Message-----
> From: Niklas Keller [mailto:me@kelunik.com]
> Sent: Thursday, January 5, 2017 2:27 AM
> To: Michael Wallner <mike@php.net>; Anatol Belski <anatol.php@belski.net>
> Cc: PHP Internals <internals@lists.php.net>
> Subject: Re: [PHP-DEV] Fwd: Monotonic Time
> 
> > […]
> 
> 
> Yes, that seemed weird to me, too. Did we miss anything, Anatol?
> 
Yeah, I thought I did that already, but well ...  The ext was more about performance testing, at the start at least. I made some refactoring to it yesterday, so it is now possible to implement an arbitrary userspace timer using the HRTime\PerformanceCounter class. Maybe should add also HRTime\Timer, but it should first get a thought about some good API approach.

The portable parts are bundled files timer.[h|c] in the hrtime repo, supporting POSIX, Windows and Mac. They can be reused, or taken as an example, for sure.

Regards

Anatol

---

## #97549 — Stanislav Malyshev — 2017-01-07T00:57:55+00:00

URL: https://externals.io/message/97502#97549 · In reply to: #97510

Hi!

> I think we can reuse parts of it to implement a function in core to access
> a monotonic time, I don't think we need to merge the extension into core.

What's wrong with just having an extension?

-- 
Stas Malyshev
smalyshev@gmail.com

---

## #97562 — Niklas Keller — 2017-01-07T19:05:08+00:00

URL: https://externals.io/message/97502#97562 · In reply to: #97549

>
> Hi!
>
> > […]
> access
> > […]
>
> What's wrong with just having an extension?
>

Do you mean an external (not bundled) extension?

Simply not having it available by default. Measuring time frames is a
pretty fundamental operation, not only for event loops.

Regards, Niklas

---

## #97740 — Niklas Keller — 2017-01-13T09:35:24+00:00

URL: https://externals.io/message/97502#97740 · In reply to: #97541

>
> > […]
> Yeah, I thought I did that already, but well ...  The ext was more about
> performance testing, at the start at least. I made some refactoring to it
> yesterday, so it is now possible to implement an arbitrary userspace timer
> using the HRTime\PerformanceCounter class. Maybe should add also
> HRTime\Timer, but it should first get a thought about some good API
> approach.
>
> The portable parts are bundled files timer.[h|c] in the hrtime repo,
> supporting POSIX, Windows and Mac. They can be reused, or taken as an
> example, for sure.


Hi Anatol,

Do you think we should merge hrtime into core or add a simple function just
like `microtime()` to ext/standard?

Regards, Niklas

---

## #97743 — Leigh — 2017-01-13T14:06:22+00:00

URL: https://externals.io/message/97502#97743 · In reply to: #97740

> Hi Anatol,
>
> Do you think we should merge hrtime into core or add a simple function just
> like `microtime()` to ext/standard?
>
> Regards, Niklas
>

It would be great if it could be a simple function, however it is going to
be difficult to produce something cross-platform and meaningful with a
single function. (I know Anatol has written portable code, I haven't looked
at it but I assume it's wrapping the various structs used by i.e.
performance counters, hrtime, etc.)

I don't think we can get away from having an object-based implementation to
wrap those internal structs, but I do think this is a useful addition
regardless of how it's presented.

---

## #97744 — Niklas Keller — 2017-01-13T15:46:13+00:00

URL: https://externals.io/message/97502#97744 · In reply to: #97743

2017-01-13 15:06 GMT+01:00 Leigh <leight@gmail.com>:

> 
>
> > […]
> just
> > […]
>
> It would be great if it could be a simple function, however it is going to
> be difficult to produce something cross-platform and meaningful with a
> single function. (I know Anatol has written portable code, I haven't looked
> at it but I assume it's wrapping the various structs used by i.e.
> performance counters, hrtime, etc.)
>
> I don't think we can get away from having an object-based implementation to
> wrap those internal structs, but I do think this is a useful addition
> regardless of how it's presented.
>

With timer.c it's very easy to have it as one function, in fact it's a
simple static method currently doing exactly what I think it should
probably do in core as a function.

http://svn.php.net/viewvc/pecl/hrtime/trunk/hrtime.c?revision=341600&view=markup
< Line 416.

Any name suggestions?

Regards, Niklas

---

## #97753 — Anatol Belski — 2017-01-14T16:07:49+00:00

URL: https://externals.io/message/97502#97753 · In reply to: #97744

Hi,

> -----Original Message-----
> From: Niklas Keller [mailto:me@kelunik.com]
> Sent: Friday, January 13, 2017 4:46 PM
> To: Leigh <leight@gmail.com>
> Cc: Anatol Belski <anatol.php@belski.net>; Michael Wallner <mike@php.net>;
> PHP Internals <internals@lists.php.net>; Bob Weinand <bwoebi@php.net>;
> Daniel Lowrey <rdlowrey@php.net>
> Subject: Re: [PHP-DEV] Fwd: Monotonic Time
> 
> 2017-01-13 15:06 GMT+01:00 Leigh <leight@gmail.com>:
> 
> > […]
> by i.e.
> > […]
> 
> With timer.c it's very easy to have it as one function, in fact it's a simple static
> method currently doing exactly what I think it should probably do in core as a
> function.
> 
> http://svn.php.net/viewvc/pecl/hrtime/trunk/hrtime.c?revision=341600&view=
> markup
> < Line 416.
> 
The PerformanceCounter class from the hrtime ext allows to implement any time measurement directly in PHP. It provides the most low level units used by the system, the ticks. To convert ticks into actual time, the tick frequency is required. The frequency can be actually hidden from the implementation, or could be exposed to PHP. Exposing might be useful for several reasons, fe if one would want to compare different systems. Anyway, these are the base bricks.

Niklas, about merging into core - not sure it needs the StopWatch class, but maybe. The performance counter class, at the very low level, could have more chance. Taking timer.c as base should be fine, too, even there is a significant improved potential down to the ASM level later, though very platform specific. In first place what would make sense to know - what exact usage would it be? More specific use case info is what is needed to discuss and figure out the required implementation.

Regards

Anatol

---

## #97754 — Niklas Keller — 2017-01-14T17:00:00+00:00

URL: https://externals.io/message/97502#97754 · In reply to: #97753

>
> Hi,
>
> > […]
> structs used
> > […]
> simple static
> > […]
> core as a
> > […]
> revision=341600&view=
> > […]
> The PerformanceCounter class from the hrtime ext allows to implement any
> time measurement directly in PHP. It provides the most low level units used
> by the system, the ticks. To convert ticks into actual time, the tick
> frequency is required. The frequency can be actually hidden from the
> implementation, or could be exposed to PHP. Exposing might be useful for
> several reasons, fe if one would want to compare different systems. Anyway,
> these are the base bricks.
>
> Niklas, about merging into core - not sure it needs the StopWatch class,
> but maybe. The performance counter class, at the very low level, could have
> more chance. Taking timer.c as base should be fine, too, even there is a
> significant improved potential down to the ASM level later, though very
> platform specific. In first place what would make sense to know - what
> exact usage would it be? More specific use case info is what is needed to
> discuss and figure out the required implementation.


Hi Anatol,

my specific use case is mainly for event loops, replacing the current
microtime calls there, e.g.
https://github.com/amphp/loop/blob/master/lib/NativeLoop.php#L62

Performance measuring is another one, but not that important to me. If
microtime drifts there, it will show wrong results, but it won't impact
applications with failures like executing DNS timeout watchers too early
and making things fail.

Regards, Niklas

---

## #98211 — Niklas Keller — 2017-02-05T19:18:30+00:00

URL: https://externals.io/message/97502#98211 · In reply to: #97754

I have implemented a `hrtime()` function which allows access to the
system's monotonic time in nanoseconds.
>
>
https://github.com/php/php-src/compare/master...kelunik:hrtime

Feedback is very welcome.

I'm not sure whether we should allow a parameter for the time unit or just
let the user do the simple calculation.

Regards, Niklas

---

## #98215 — Anatol Belski — 2017-02-06T12:33:09+00:00

URL: https://externals.io/message/97502#98215 · In reply to: #98211

Hi Niklas,

> -----Original Message-----
> From: Niklas Keller [mailto:me@kelunik.com]
> Sent: Sunday, February 5, 2017 8:19 PM
> To: Anatol Belski <anatol.php@belski.net>
> Cc: Leigh <leight@gmail.com>; Michael Wallner <mike@php.net>; PHP Internals
> <internals@lists.php.net>; Bob Weinand <bwoebi@php.net>; Daniel Lowrey
> <rdlowrey@php.net>
> Subject: Re: [PHP-DEV] Fwd: Monotonic Time
> 
> I have implemented a `hrtime()` function which allows access to the system's
> monotonic time in nanoseconds.
> 
Nice for the start.

> 
> https://github.com/php/php-src/compare/master...kelunik:hrtime
> 
> 
> Feedback is very welcome.
> 
> I'm not sure whether we should allow a parameter for the time unit or just let
> the user do the simple calculation.
> 
I'd see this integration a bit different, as the goal is to put it into the core.  Here some quick points to maybe think about

- on the m4 side, symbols need to be checked
- the PHP internal and user stuff should be integrated tight into the timer.c file, 
- a finer usage with the concrete platform should be taken care of, thus avoiding unnecessary function calls and conversions back/forth as you can use
- there might be a situation, where the monotonic API could be used internally before modules are initialized
- the symbols exported need to be renamed, probably prefix with php_monotonic_*, like php_monotonic_timer_current(), etc.
- but aso, probably not all the symbols should be exported

With the names and API, probably some more clarity should be. AFM, the low level units should be exposed, rather than a concrete time. Also, the name `hrtime()` is probably not much speaking. Maybe these three?

sys_get_monotonic_ticks()
sys_get_monotonic_freq()
sys_get_monotonic_nanotime() or even - sys_get_monotonic_time(int $unit = NANOSECOND)

Regarding to "sys_get_*" scheme with these. But in general, probably nanoseconds were enough for the general case and fast, the pure ticks were for the advanced usage.

In general, probably for the core it should be done a more robust way, some parts on the original lib should get more error checks and improved. It would be probably more handy to discuss the further on the PR page.

Regards

Anatol

---

## #98217 — Fleshgrinder — 2017-02-06T16:45:01+00:00

URL: https://externals.io/message/97502#98217 · In reply to: #98215

> With the names and API, probably some more clarity should be. AFM,
> the low level units should be exposed, rather than a concrete time.
> Also, the name `hrtime()` is probably not much speaking. Maybe these
> three?
> 
> sys_get_monotonic_ticks()
> sys_get_monotonic_freq() 
> sys_get_monotonic_nanotime() or even -
> sys_get_monotonic_time(int $unit = NANOSECOND)
> 
> Regarding to "sys_get_*" scheme with these. But in general, probably
> nanoseconds were enough for the general case and fast, the pure ticks
> were for the advanced usage.
> 
> In general, probably for the core it should be done a more robust
> way, some parts on the original lib should get more error checks and
> improved. It would be probably more handy to discuss the further on
> the PR page.
> 
> Regards
> 
> Anatol
> 

Hey guys! :)

Please do not introduce more functions that require flags, it makes code
hard to read. It's much better to have dedicated functions that provide
exactly what is requested. A good bad example is `microtime()` vs
`microtime(true)`. :(

`sys_get_monotonic_nanotime()` is rather long but at least descriptive.
Obviously providing a class could help with naming a lot and future
extension would be easy, e.g. `MonotonicTime::getNanoseconds()`.

-- 
Richard "Fleshgrinder" Fussenegger
