Project

General

Profile

Feature #8658

Process.clock_gettime

Added by akr (Akira Tanaka) over 6 years ago. Updated over 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:56087]

Description

How about adding a new method, Process.clock_gettime(clk_id) ?

Recently there were two feature request for measuring time.
Feature #8640 https://bugs.ruby-lang.org/issues/8640
Feature #8096 https://bugs.ruby-lang.org/issues/8096

It seems they are somewhat different.

clock_gettime() function defined by POSIX is a good
candidate for providing as a method.
I think it can supports the both request.

Also, it has less possible design choices than the requests
because clock_gettime() is defined by POSIX.
People familiar to POSIX can learn the method more easily.

I wrote a patch to implement Process.clock_gettime.
This method can be used as follows.

% ./ruby -e 'p Process.clock_gettime(Process::CLOCK_MONOTONIC)'
2701692957811563

Several considerations:

I implemented the method as a module function of Process.
It is same as Process.times.
I expect clock_gettime is used mainly for measuring
time interval and wall clock time is not important.
So I didn't use Time.

The method returns a number of nanoseconds as an integer.
It is not so unexpected if user knows clock_gettime() in POSIX.

clock_gettime() returns it as struct timespec
which contains two fields: tv_sec and tv_nsec.

Although tv_sec is time_t, Time is not appropriate because
the origin (zero) can be other than the Epoch.
Actually CLOCK_MONOTONIC means elapsed time since
the system start-up time on Linux.

Also, I expect the result is subtracted in most case:
t1 = Process.clock_gettime(...)
...
t2 = Process.clock_gettime(...)
t = t2 - t1
So the result should be easy to subtract.
An array such as [sec, nsec] is difficult to subtract.

The result is an integer, not a float.
IEEE 754 double is not enough to represent the result
of clock_gettime(CLOCK_REALTIME).
It contains 19 digits in decimal now but IEEE 754 double
can represent only 15 digits.

On LP64 systems, Fixnum can represent 2*62-1.
So (2
*62-1)/(365.25*24*60*60*1e9)=146.1 years are representable
without object allocation.

On ILP32 and LLP64 systems, Fixnum can represent 2*30-1.
So (2
*30-1)/1e9=1.07 seconds are representable
without object allocation.
This means Bignum allocations are mostly required except
the origin is very recent.

clock_gettime() is defined by POSIX.
Linux, NetBSD, FreeBSD, OpenBSD has it, at least.

If clock_gettime() is not available,
an emulation layer for CLOCK_REALTIME is implementable
using gettimeofday().
(not implemented yet, though.)

Any comments?


Files

clock_gettime.patch (4.11 KB) clock_gettime.patch akr (Akira Tanaka), 07/19/2013 09:32 PM
clock_gettime-2.patch (7.58 KB) clock_gettime-2.patch akr (Akira Tanaka), 07/20/2013 07:39 PM
clock_gettime-3.patch (8.3 KB) clock_gettime-3.patch akr (Akira Tanaka), 08/01/2013 09:10 PM
clock_gettime-4.patch (9.2 KB) clock_gettime-4.patch akr (Akira Tanaka), 08/05/2013 09:50 PM

Related issues

Related to CommonRuby - Feature #8096: introduce Time.current_timestampFeedback03/15/2013matz (Yukihiro Matsumoto)Actions
Related to CommonRuby - Feature #8640: Add Time#elapsed to return nanoseconds since creationOpen07/16/2013Actions
Related to CommonRuby - Feature #8777: Process.mach_absolute_timeClosed08/11/2013Actions

Also available in: Atom PDF