Forum: Ruby-core [ruby-trunk - Feature #8658][Open] Process.clock_gettime

B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 akr (Akira Tanaka) (Guest)
on 2013-07-19 14:33
(Received via mailing list)
Issue #8658 has been reported by akr (Akira Tanaka).

----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658

Author: akr (Akira Tanaka)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


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?
02da662c083396641da96c1d32fc86ed?d=identicon&s=25 kosaki (Motohiro KOSAKI) (Guest)
on 2013-07-19 21:52
(Received via mailing list)
Issue #8658 has been updated by kosaki (Motohiro KOSAKI).


First, Process.times() returns user time and system time and they are
process  specific. But Process::CLOCK_MONOTONIC is not per-process time.

Second, Linux's CLOCK_MONOTONIC_RAW has the same behavior BSD's
CLOCK_MONOTONIC. And, an application which measures a performance need
to use CLOCK_MONOTONIC_RAW for avoiding ntp confusing. Then, we should
do 1) exporse CLOCK_MONOTONIC_RAW or 2)
Process.clock_gettime(Process::CLOCK_MONOTONIC) uses
CLOCK_MONOTONIC_RAW internally.

Third, using float is a good ruby convention. If we need to use inter
(for precision and performance?), the method should have a precision
explanation, likes get_time_nanosecond. I mean, ruby interpreter can't
warn nor detect following mistake.

a = foo # this is usec
b = bar # this is nsec
c = a + b

then, we should warn by method name verbosely. IMHO.






----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-40587

Author: akr (Akira Tanaka)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


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?
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 akr (Akira Tanaka) (Guest)
on 2013-07-20 12:39
(Received via mailing list)
Issue #8658 has been updated by akr (Akira Tanaka).

File clock_gettime-2.patch added

kosaki (Motohiro KOSAKI) wrote:
> First, Process.times() returns user time and system time and they are process
specific. But Process::CLOCK_MONOTONIC is not per-process time.

Yes.  Users can choose any clock with Process.clock_gettime unlike other
proposals (#8640, #8096).

It seems many people use CLOCK_REALTIME to measure a time interval,
though.

> Second, Linux's CLOCK_MONOTONIC_RAW has the same behavior BSD's CLOCK_MONOTONIC.
And, an application which measures a performance need to use CLOCK_MONOTONIC_RAW
for avoiding ntp confusing. Then, we should do 1) exporse CLOCK_MONOTONIC_RAW or
2)  Process.clock_gettime(Process::CLOCK_MONOTONIC) uses  CLOCK_MONOTONIC_RAW
internally.

OS specific CLOCK_* constants can be defined.
Since Process.clock_gettime is a primitive, exchange clk_id is not a
good idea.

> Third, using float is a good ruby convention. If we need to use inter (for
precision and performance?), the method should have a precision explanation, 
likes
get_time_nanosecond. I mean, ruby interpreter can't warn nor detect following
mistake.
>
> a = foo # this is usec
> b = bar # this is nsec
> c = a + b
>
> then, we should warn by method name verbosely. IMHO.

Hm.  It is acceptable as far as the exact result (number of nanoseconds)
can be obtained.

After thinking while, I find Process.clock_gettime(clk_id, unit).
unit is an optional argument and :nanoseconds specifies the nanoseconds.
This can help performance on ILP33 because :microseconds with
CLOCK_PROCESS_CPUTIME_ID
will not use Bignum until 1073 seconds after process start up.

I updated the patch.

----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-40590

Author: akr (Akira Tanaka)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


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?
F52e87b92cafb1e8c6d155076b56ecff?d=identicon&s=25 "Martin J. Dürst" <duerst@it.aoyama.ac.jp> (Guest)
on 2013-07-21 07:51
(Received via mailing list)
Hello Akira,

On 2013/07/19 21:32, akr (Akira Tanaka) wrote:

> 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.

Don't your calculations ignore the fact that Fixnums are signed? Or do
you have a way to use negative amounts of nanoseconds, too?

Regards,   Martin.
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 Tanaka Akira (Guest)
on 2013-07-21 09:56
(Received via mailing list)
2013/7/21 "Martin J. Drst" <duerst@it.aoyama.ac.jp>:
>> This means Bignum allocations are mostly required except
>> the origin is very recent.
>
>
> Don't your calculations ignore the fact that Fixnums are signed? Or do you
> have a way to use negative amounts of nanoseconds, too?

% ./ruby -ve 'p (2**62-1).class, (2**62).class'
ruby 2.1.0dev (2013-07-21 trunk 42095) [x86_64-linux]
Fixnum
Bignum

% ./ruby -ve 'p (2**30-1).class, (2**30).class'
ruby 2.1.0dev (2013-07-21 trunk 42095) [i686-linux]
Fixnum
Bignum

What's the problem?
C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 Eregon (Benoit Daloze) (Guest)
on 2013-07-21 12:15
(Received via mailing list)
Issue #8658 has been updated by Eregon (Benoit Daloze).


While I appreciate Ruby is not always taking the lowest common
denominator for functionality (fork, etc),
we need a counterpart for Windows and OS X at least.

https://github.com/copiousfreetime/hitimes does it pretty nicely and I
would really enjoy seeing the functionality to measure a precise
interval in core.

We should have a unified method for clock_gettime(),
mach_absolute_time() and QueryPerformanceCounter().
Actually, I think it would be better to have an API allowing to have the
time difference directly in seconds (higher level and the concern for
allocating is no more relevant, any unit can be used internally).

And this feature is not always compatible with the timestamp (given they
are monotonic clocks), so I think there should be two separate methods.

naruse gave a very useful link in #8096,
http://www.python.org/dev/peps/pep-0418/ .
I do not wish for a so large API, but I think we should have the
timestamp functionality like time.time()
and a precise performance counter like time.perf_counter().

I would be fine having the clock_id as a parameter for supporting
platforms if it proves really useful.
----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-40598

Author: akr (Akira Tanaka)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


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?
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 Tanaka Akira (Guest)
on 2013-07-23 17:00
(Received via mailing list)
2013/7/21 Eregon (Benoit Daloze) <redmine@ruby-lang.org>:
>
> Issue #8658 has been updated by Eregon (Benoit Daloze).
>
>
> While I appreciate Ruby is not always taking the lowest common denominator for
functionality (fork, etc),
> we need a counterpart for Windows and OS X at least.

Users of such OSs can contribute an emulation function for
clock_gettime.

> naruse gave a very useful link in #8096,
http://www.python.org/dev/peps/pep-0418/ .
> I do not wish for a so large API, but I think we should have the timestamp
functionality like time.time()
> and a precise performance counter like time.perf_counter().

PEP 0418 mentions that python provide clock_gettime as
time.clock_gettime.
PEP 0418 doesn't mean providing clock_gettime itself is bad idea.

Higer level methods may be useful but what I intend in this issue is a
low level primitive.
C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 Eregon (Benoit Daloze) (Guest)
on 2013-07-23 18:22
(Received via mailing list)
Issue #8658 has been updated by Eregon (Benoit Daloze).


akr (Akira Tanaka) wrote:
>  > While I appreciate Ruby is not always taking the lowest common denominator
for functionality (fork, etc),
>  > we need a counterpart for Windows and OS X at least.
>
>  Users of such OSs can contribute an emulation function for clock_gettime.

A very poor one as mapping to Linux/UNIX constants would just confuse
people.
I do not think the UNIX API clock_gettime() for this is the most
suitable,
it does not abstract the functionality and the name/usage is not very
ruby-like.

I think FFI would be a good way if someone need direct access to that
low-level C function (except for accessing the constants, that would not
be handy).

>  > naruse gave a very useful link in #8096,
http://www.python.org/dev/peps/pep-0418/ .
>  > I do not wish for a so large API, but I think we should have the timestamp
functionality like time.time()
>  > and a precise performance counter like time.perf_counter().
>
>  PEP 0418 mentions that python provide clock_gettime as time.clock_gettime.
>  PEP 0418 doesn't mean providing clock_gettime itself is bad idea.

I believe providing a method which is only available in a quite
restricted set of platforms is to be avoided.
In Python it is simply not defined on non-supporting platforms.

>  Higer level methods may be useful but what I intend in this issue is a
>  low level primitive.

To which use-cases other than benchmarking do you think?

I want Ruby to propose a nice and precise way to benchmark code *not*
requiring the user to know about every detail of available clocks/timers
under every platform.
----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-40625

Author: akr (Akira Tanaka)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


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?
02da662c083396641da96c1d32fc86ed?d=identicon&s=25 KOSAKI Motohiro (Guest)
on 2013-07-23 20:09
(Received via mailing list)
(7/20/13 6:39 AM), akr (Akira Tanaka) wrote:
> It seems many people use CLOCK_REALTIME to measure a time interval, though.
So, Why do you choice Process.clock_gettime() instead of
Time.clock_gettime()?


>> Second, Linux's CLOCK_MONOTONIC_RAW has the same behavior BSD's
CLOCK_MONOTONIC. And, an application which measures a performance need to use
CLOCK_MONOTONIC_RAW for avoiding ntp confusing. Then, we should do 1) exporse
CLOCK_MONOTONIC_RAW or 2)  Process.clock_gettime(Process::CLOCK_MONOTONIC) uses
CLOCK_MONOTONIC_RAW internally.
>
> OS specific CLOCK_* constants can be defined.
> Since Process.clock_gettime is a primitive, exchange clk_id is not a good idea.

Hm. OK.


> After thinking while, I find Process.clock_gettime(clk_id, unit).
> unit is an optional argument and :nanoseconds specifies the nanoseconds.
> This can help performance on ILP33 because :microseconds with
CLOCK_PROCESS_CPUTIME_ID
> will not use Bignum until 1073 seconds after process start up.
>
> I updated the patch.

An optional argument sound good idea.

thanks.
C4e88907313843cf07f6d85ba8162120?d=identicon&s=25 jonforums (Jon Forums) (Guest)
on 2013-07-23 20:14
(Received via mailing list)
Issue #8658 has been updated by jonforums (Jon Forums).


Eregon (Benoit Daloze) wrote:
> I think FFI would be a good way if someone need direct access to that low-level
C function (except for accessing the constants, that would not be handy).
>
It's great to see a focus on cross-platform impl issues :)

Has anyone spelunked libuv's awesomeness for inspiration on a nice
cross-platform implementation style?

  # general header niceness
  https://github.com/joyent/libuv/blob/master/includ...
    https://github.com/joyent/libuv/blob/master/includ...
    https://github.com/joyent/libuv/blob/master/include/uv-win.h

  # common timer API
  https://github.com/joyent/libuv/blob/master/includ...

  # internal platform specific header timer niceness
  https://github.com/joyent/libuv/blob/master/src/un...

  # platform specific impl niceness
  https://github.com/joyent/libuv/blob/master/src/wi...
  https://github.com/joyent/libuv/blob/master/src/un...
  https://github.com/joyent/libuv/blob/master/src/un...
----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-40627

Author: akr (Akira Tanaka)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


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?
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 Tanaka Akira (Guest)
on 2013-07-24 03:53
(Received via mailing list)
2013/7/24 KOSAKI Motohiro <kosaki.motohiro@gmail.com>:

> So, Why do you choice Process.clock_gettime() instead of
> Time.clock_gettime()?

I don't like the result value of clock_gettime(CLOCK_REALTIME) because
the value is interpreted differently between systems which use
leapseconds and not.
Time.now should be used instead.

The patch defines Process::CLOCK_REALTIME but it is just for
consistency.
I felt definining CLOCK_* constants except CLOCK_REALTIME is too
inconsistent.

The expected my main usecase would be CLOCK_PROCESS_CPUTIME_ID (or
CLOCK_THREAD_CPUTIME_ID).
For example, I use Process.times for measure Bignum speed but
Process.times cannot measure under 10ms on my environment.
Repeating target operation (as I do) improves precision but
high resolution clocks can be used to obtain similar precision
with less repeatation.
02da662c083396641da96c1d32fc86ed?d=identicon&s=25 KOSAKI Motohiro (Guest)
on 2013-07-25 19:47
(Received via mailing list)
(7/23/13 9:50 PM), Tanaka Akira wrote:
> 2013/7/24 KOSAKI Motohiro <kosaki.motohiro@gmail.com>:
>
>> So, Why do you choice Process.clock_gettime() instead of
>> Time.clock_gettime()?
>
> I don't like the result value of clock_gettime(CLOCK_REALTIME) because
> the value is interpreted differently between systems which use
> leapseconds and not.
> Time.now should be used instead.

Hmm. OK.


> The patch defines Process::CLOCK_REALTIME but it is just for consistency.
> I felt definining CLOCK_* constants except CLOCK_REALTIME is too inconsistent.
>
> The expected my main usecase would be CLOCK_PROCESS_CPUTIME_ID (or
> CLOCK_THREAD_CPUTIME_ID).
> For example, I use Process.times for measure Bignum speed but
> Process.times cannot measure under 10ms on my environment.
> Repeating target operation (as I do) improves precision but
> high resolution clocks can be used to obtain similar precision
> with less repeatation.

Really? I don't think so because CLOCK_*_CPUTIME_ID have less precious
than
CLOCK_REALTIME. following "t" often show 0 on several OSs.


t0 = clock_gettime(CLOCK_THREAD_CPUTIME_ID)
# blah blah blah
t1 = clock_gettime(CLOCK_THREAD_CPUTIME_ID)
t = t1 - t0
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 Tanaka Akira (Guest)
on 2013-07-26 05:42
(Received via mailing list)
2013/7/24 Eregon (Benoit Daloze) <redmine@ruby-lang.org>:
> Issue #8658 has been updated by Eregon (Benoit Daloze).
>
> A very poor one as mapping to Linux/UNIX constants would just confuse people.
> I do not think the UNIX API clock_gettime() for this is the most suitable,
> it does not abstract the functionality and the name/usage is not very ruby-like.

If constants defined by Unix is not suitable, original constants can be
defined.

Ruby uses POSIX functions in general.
So I think clock_gettime is very Ruby-ish (and I guess it is easier
than original design
to persuade matz).

> I think FFI would be a good way if someone need direct access to that low-level
C function (except for accessing the constants, that would not be handy).

How FFI can be used to call clock_gettime?
I don't have experience with FFI.

> I believe providing a method which is only available in a quite restricted set
of platforms is to be avoided.
> In Python it is simply not defined on non-supporting platforms.

At least, CLOCK_REALTIME can be emulated on all platforms.
Other clocks may be too, on some platforms.

Also, Ruby provides many platform dependent methods in Process.

>>  Higer level methods may be useful but what I intend in this issue is a
>>  low level primitive.
>
> To which use-cases other than benchmarking do you think?

I expect that I use CLOCK_PROCESS_CPUTIME_ID.

> I want Ruby to propose a nice and precise way to benchmark code *not* requiring
the user to know about every detail of available clocks/timers under every
platform.

It is good to have such high level methods but
it doesn't conflict with low level methods.
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 Tanaka Akira (Guest)
on 2013-07-26 05:55
(Received via mailing list)
2013/7/26 KOSAKI Motohiro <kosaki.motohiro@gmail.com>:

> Really? I don't think so because CLOCK_*_CPUTIME_ID have less precious than
> CLOCK_REALTIME. following "t" often show 0 on several OSs.
>
>
> t0 = clock_gettime(CLOCK_THREAD_CPUTIME_ID)
> # blah blah blah
> t1 = clock_gettime(CLOCK_THREAD_CPUTIME_ID)
> t = t1 - t0

At least, my system can return 1ns unit.
(It doesn't mean 1ns accuracy, of course.)

In following result, 4666 and 4667 are returned.

% ./ruby -ve '
t1 = Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID,
:nanoseconds)
while true
  t2 = Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID,
:nanoseconds)
  p t2-t1
  t1 = t2
end
'|head -20|sort -n
ruby 2.1.0dev (2013-07-19 trunk 42049) [x86_64-linux]
2861
3984
4154
4189
4222
4267
4452
4567
4620
4666
4667
4771
4870
4920
5296
6155
6428
12690
20290
-e:5:in `p': Broken pipe (Errno::EPIPE)
  from -e:5:in `<main>'
% uname -mrsv
Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64

Other platforms can behave differently, though.
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 Tanaka Akira (Guest)
on 2013-07-27 01:48
(Received via mailing list)
2013/7/26 Tanaka Akira <akr@fsij.org>:
>
>   t1 = t2
> end
> '|head -20|sort -n

CLOCK_THREAD_CPUTIME_ID can return 1ns unit too.

% ./ruby -ve '
t1 = Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID,
:nanoseconds)
while true
  t2 = Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID,
:nanoseconds)
  p t2-t1
  t1 = t2
end
'|head -20|sort -n
ruby 2.1.0dev (2013-07-19 trunk 42049) [x86_64-linux]
2091
3913
3936
3939
3975
3976
3978
4281
4466
4473
4516
4563
4666
4706
-e:5:in `p'5604
6196
6342
13047
19388
: Broken pipe (Errno::EPIPE)
  from -e:5:in `<main>'

(3975 and 3976 is returned.)

CLOCK_THREAD_CPUTIME_ID may be preferable than CLOCK_PROCESS_CPUTIME_ID
for
measuring Bignum speed because it is purely single thread.
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 akr (Akira Tanaka) (Guest)
on 2013-08-01 14:10
(Received via mailing list)
Issue #8658 has been updated by akr (Akira Tanaka).

File clock_gettime-3.patch added

I updated the patch to emulate CLOCK_REALTIME using gettimeofday.
----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-40796

Author: akr (Akira Tanaka)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


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?
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 akr (Akira Tanaka) (Guest)
on 2013-08-05 14:50
(Received via mailing list)
Issue #8658 has been updated by akr (Akira Tanaka).

File clock_gettime-4.patch added

I updated the patch for Process.clock_gettime.
The patch, clock_gettime-4.patch, supports gettimeofday() and time(),
even when clock_gettime() is available.

----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-40901

Author: akr (Akira Tanaka)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


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?
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 akr (Akira Tanaka) (Guest)
on 2013-08-11 05:13
(Received via mailing list)
Issue #8658 has been updated by akr (Akira Tanaka).

Status changed from Open to Closed

I committed r42504 to implement Process.clock_gettime method.
This is result of the meeting:
https://bugs.ruby-lang.org/projects/ruby/wiki/Deve...

This doesn't mean that high level API is rejected.
Feel free to discuss it.

----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-41080

Author: akr (Akira Tanaka)
Status: Closed
Priority: Normal
Assignee:
Category:
Target version:


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?
F1d37642fdaa1662ff46e4c65731e9ab?d=identicon&s=25 Charles Nutter (headius)
on 2013-10-01 20:49
(Received via mailing list)
Issue #8658 has been updated by headius (Charles Nutter).


I missed the discussion on this, but here's the summary of JRuby/JVM
case:

If monotonic clock is available at OS level, System.nanoTime is
equivalent to clock_gettime(CLOCK_MONOTONIC). I suppose there may be
some embedded systems or obscure platforms that don't have a monotonic
clock, but otherwise I'm guessing this is going to be pretty universal
across *nixes. The code in JDK is in
http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/...
at line 1453.

If monotonic clock is not available on *nix, JVM will fall back on
gettimeofday transparently. I'm investigating whether it is possible for
us to query this behavior.

System.currentTimeMillis is just a plain gettimeofday call, which in the
Process::clock_gettime API is called GETTIMEOFDAY_BASED_CLOCK_REALTIME.

So JRuby will always be able to support
GETTIMEOFDAY_BASED_CLOCK_REALTIME via System.currentTimeMillis,
CLOCK_MONOTONIC when nanoTime is monotonic, and the other forms when
we're able to make a native downcall. Initially, we will probably just
support these two.

I HAVE A QUESTION, however... what about Windows? There's no mention at
all in the rdoc about Windows support. I need to investigate what
currentTimeMillis and nanoTime do on JVM on Windows.
----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-42175

Author: akr (Akira Tanaka)
Status: Closed
Priority: Normal
Assignee:
Category:
Target version:


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?
F1d37642fdaa1662ff46e4c65731e9ab?d=identicon&s=25 Charles Nutter (headius)
on 2013-10-01 21:02
(Received via mailing list)
Issue #8658 has been updated by headius (Charles Nutter).


JRuby issue for this feature: https://github.com/jruby/jruby/issues/1056

Windows information for JVM:

System.currentTimeMillis is always implemented using win32
GetSystemTimeAsFileTime function.

http://msdn.microsoft.com/en-us/library/windows/de...

System.nanoTime is implemented using QueryPerformanceCounter if
available (Windows 2000 or higher), falling back on currentTimeMillis if
it is not. This appears (by looking around in other articles) to be
"rawtime", so perhaps equivalent to CLOCK_MONOTONIC_RAW? I think that
would suffice for us to use it for CLOCK_MONOTONIC, but it's not very
clear from available info.

http://msdn.microsoft.com/en-us/library/windows/de...

The latter article has a link in comments to a HOWTO on implementing a
high-resolution timer on Windows. Bottom line is that some
synchronization between the two functions is necessary, and it's pretty
ugly.
----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-42176

Author: akr (Akira Tanaka)
Status: Closed
Priority: Normal
Assignee:
Category:
Target version:


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?
F1d37642fdaa1662ff46e4c65731e9ab?d=identicon&s=25 Charles Nutter (headius)
on 2013-10-01 22:13
(Received via mailing list)
Issue #8658 has been updated by headius (Charles Nutter).


Implementation in JRuby:
https://github.com/jruby/jruby/commit/8c066241bd84...
----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-42181

Author: akr (Akira Tanaka)
Status: Closed
Priority: Normal
Assignee:
Category:
Target version:


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?
B11f10c4cd9d53970e7be20caa43f940?d=identicon&s=25 Tanaka Akira (Guest)
on 2013-10-02 00:29
(Received via mailing list)
2013/10/2 headius (Charles Nutter) <headius@headius.com>:

> I HAVE A QUESTION, however... what about Windows? There's no mention at all in
the rdoc about Windows support. I need to investigate what currentTimeMillis and
nanoTime do on JVM on Windows.

usa-san implemented clock_gettime() function in win32/win32.c.
9361878d459f1709feec780518946ee5?d=identicon&s=25 naruse (Yui NARUSE) (Guest)
on 2013-10-02 06:30
(Received via mailing list)
Issue #8658 has been updated by naruse (Yui NARUSE).


akr (Akira Tanaka) wrote:
> 2013/10/2 headius (Charles Nutter) <headius@headius.com>:
>
>  > I HAVE A QUESTION, however... what about Windows? There's no mention at all
in the rdoc about Windows support. I need to investigate what currentTimeMillis
and nanoTime do on JVM on Windows.
>
>  usa-san implemented clock_gettime() function in win32/win32.c.

It is r42557 and other commits
----------------------------------------
Feature #8658: Process.clock_gettime
https://bugs.ruby-lang.org/issues/8658#change-42196

Author: akr (Akira Tanaka)
Status: Closed
Priority: Normal
Assignee:
Category:
Target version:


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?
This topic is locked and can not be replied to.