Feature #8658

Process.clock_gettime

Added by Akira Tanaka 9 months ago. Updated 7 months ago.

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

Description

How about adding a new method, Process.clockgettime(clkid) ?

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.clockgettime(Process::CLOCKMONOTONIC)'
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.

clockgettime() returns it as struct timespec
which contains two fields: tv
sec and tv_nsec.

Although tvsec is timet, 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.clockgettime(...)
...
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 clockgettime(CLOCKREALTIME).
It contains 19 digits in decimal now but IEEE 754 double
can represent only 15 digits.

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

On ILP32 and LLP64 systems, Fixnum can represent 230-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 clockgettime() is not available,
an emulation layer for CLOCK
REALTIME is implementable
using gettimeofday().
(not implemented yet, though.)

Any comments?

clock_gettime.patch Magnifier (4.11 KB) Akira Tanaka, 07/19/2013 09:32 PM

clock_gettime-2.patch Magnifier (7.58 KB) Akira Tanaka, 07/20/2013 07:39 PM

clock_gettime-3.patch Magnifier (8.3 KB) Akira Tanaka, 08/01/2013 09:10 PM

clock_gettime-4.patch Magnifier (9.2 KB) Akira Tanaka, 08/05/2013 09:50 PM


Related issues

Related to CommonRuby - Feature #8096: introduce Time.current_timestamp Feedback 03/15/2013
Related to CommonRuby - Feature #8640: Add Time#elapsed to return nanoseconds since creation Open 07/16/2013
Related to CommonRuby - Feature #8777: Process.mach_absolute_time Closed 08/11/2013

Associated revisions

Revision 42573
Added by Yui NARUSE 8 months ago

History

#1 Updated by Motohiro KOSAKI 9 months ago

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 CLOCKMONOTONICRAW has the same behavior BSD's CLOCKMONOTONIC. And, an application which measures a performance need to use CLOCKMONOTONICRAW for avoiding ntp confusing. Then, we should do 1) exporse CLOCKMONOTONICRAW or 2) Process.clockgettime(Process::CLOCKMONOTONIC) uses CLOCKMONOTONIC_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 gettimenanosecond. 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.

#2 Updated by Akira Tanaka 9 months ago

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 CLOCKMONOTONICRAW has the same behavior BSD's CLOCKMONOTONIC. And, an application which measures a performance need to use CLOCKMONOTONICRAW for avoiding ntp confusing. Then, we should do 1) exporse CLOCKMONOTONICRAW or 2) Process.clockgettime(Process::CLOCKMONOTONIC) uses CLOCKMONOTONIC_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 gettimenanosecond. 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.clockgettime(clkid, unit).
unit is an optional argument and :nanoseconds specifies the nanoseconds.
This can help performance on ILP33 because :microseconds with CLOCKPROCESSCPUTIME_ID
will not use Bignum until 1073 seconds after process start up.

I updated the patch.

#3 Updated by Martin Dürst 9 months ago

Hello Akira,

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

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

On ILP32 and LLP64 systems, Fixnum can represent 230-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.

#4 Updated by Akira Tanaka 9 months ago

2013/7/21 "Martin J. Dürst" duerst@it.aoyama.ac.jp:

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

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

On ILP32 and LLP64 systems, Fixnum can represent 230-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?

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

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

What's the problem?
--
Tanaka Akira

#5 Updated by Benoit Daloze 9 months ago

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 clockgettime(), machabsolute_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.

#6 Updated by Akira Tanaka 9 months ago

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 clockgettime as time.clockgettime.
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.
--
Tanaka Akira

#7 Updated by Benoit Daloze 9 months ago

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 clockgettime as time.clockgettime.
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.

#8 Updated by Jon Forums 9 months ago

Eregon (Benoit Daloze) wrote:

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 clockgettime as time.clockgettime.
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.

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/include/uv.h#L62-L67
https://github.com/joyent/libuv/blob/master/include/uv-unix.h
https://github.com/joyent/libuv/blob/master/include/uv-win.h

# common timer API
https://github.com/joyent/libuv/blob/master/include/uv.h#L1873-L1881

# internal platform specific header timer niceness
https://github.com/joyent/libuv/blob/master/src/unix/internal.h#L180-L181

# platform specific impl niceness
https://github.com/joyent/libuv/blob/master/src/win/util.c#L443-L465
https://github.com/joyent/libuv/blob/master/src/unix/core.c#L78-L80
https://github.com/joyent/libuv/blob/master/src/unix/linux-core.c#L245-L249

#9 Updated by Motohiro KOSAKI 9 months ago

(7/20/13 6:39 AM), akr (Akira Tanaka) wrote:

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.

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

Second, Linux's CLOCKMONOTONICRAW has the same behavior BSD's CLOCKMONOTONIC. And, an application which measures a performance need to use CLOCKMONOTONICRAW for avoiding ntp confusing. Then, we should do 1) exporse CLOCKMONOTONICRAW or 2) Process.clockgettime(Process::CLOCKMONOTONIC) uses CLOCKMONOTONIC_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.

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 gettimenanosecond. 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.clockgettime(clkid, unit).
unit is an optional argument and :nanoseconds specifies the nanoseconds.
This can help performance on ILP33 because :microseconds with CLOCKPROCESSCPUTIME_ID
will not use Bignum until 1073 seconds after process start up.

I updated the patch.

An optional argument sound good idea.

thanks.

#10 Updated by Akira Tanaka 9 months ago

2013/7/24 KOSAKI Motohiro kosaki.motohiro@gmail.com:

So, Why do you choice Process.clockgettime() instead of
Time.clock
gettime()?

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

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

The expected my main usecase would be CLOCKPROCESSCPUTIMEID (or
CLOCK
THREADCPUTIMEID).
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.
--
Tanaka Akira

#11 Updated by Motohiro KOSAKI 9 months ago

(7/23/13 9:50 PM), Tanaka Akira wrote:

2013/7/24 KOSAKI Motohiro kosaki.motohiro@gmail.com:

So, Why do you choice Process.clockgettime() instead of
Time.clock
gettime()?

I don't like the result value of clockgettime(CLOCKREALTIME) 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::CLOCKREALTIME but it is just for consistency.
I felt definining CLOCK
* constants except CLOCK_REALTIME is too inconsistent.

The expected my main usecase would be CLOCKPROCESSCPUTIMEID (or
CLOCK
THREADCPUTIMEID).
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*CPUTIMEID have less precious than
CLOCK
REALTIME. following "t" often show 0 on several OSs.

t0 = clockgettime(CLOCKTHREADCPUTIMEID)
# blah blah blah
t1 = clockgettime(CLOCKTHREADCPUTIMEID)
t = t1 - t0

#12 Updated by Akira Tanaka 9 months ago

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 CLOCKPROCESSCPUTIME_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.
--
Tanaka Akira

#13 Updated by Akira Tanaka 9 months ago

2013/7/26 KOSAKI Motohiro kosaki.motohiro@gmail.com:

Really? I don't think so because CLOCK*CPUTIMEID have less precious than
CLOCK
REALTIME. following "t" often show 0 on several OSs.

t0 = clockgettime(CLOCKTHREADCPUTIMEID)

blah blah blah

t1 = clockgettime(CLOCKTHREADCPUTIMEID)
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.clockgettime(Process::CLOCKPROCESSCPUTIMEID, :nanoseconds)
while true
t2 = Process.clockgettime(Process::CLOCKPROCESSCPUTIMEID, :nanoseconds)
p t2-t1
t1 = t2
end
'|head -20|sort -n
ruby 2.1.0dev (2013-07-19 trunk 42049) [x8664-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
'
% uname -mrsv
Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86
64

Other platforms can behave differently, though.
--
Tanaka Akira

#14 Updated by Akira Tanaka 9 months ago

2013/7/26 Tanaka Akira akr@fsij.org:

2013/7/26 KOSAKI Motohiro kosaki.motohiro@gmail.com:

Really? I don't think so because CLOCK*CPUTIMEID have less precious than
CLOCK
REALTIME. following "t" often show 0 on several OSs.

t0 = clockgettime(CLOCKTHREADCPUTIMEID)

blah blah blah

t1 = clockgettime(CLOCKTHREADCPUTIMEID)
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.clockgettime(Process::CLOCKPROCESSCPUTIMEID, :nanoseconds)
while true
t2 = Process.clockgettime(Process::CLOCKPROCESSCPUTIMEID, :nanoseconds)
p t2-t1
t1 = t2
end
'|head -20|sort -n

CLOCKTHREADCPUTIME_ID can return 1ns unit too.

% ./ruby -ve '
t1 = Process.clockgettime(Process::CLOCKTHREADCPUTIMEID, :nanoseconds)
while true
t2 = Process.clockgettime(Process::CLOCKTHREADCPUTIMEID, :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
'

(3975 and 3976 is returned.)

CLOCKTHREADCPUTIMEID may be preferable than CLOCKPROCESSCPUTIMEID for
measuring Bignum speed because it is purely single thread.
--
Tanaka Akira

#15 Updated by Akira Tanaka 9 months ago

I updated the patch to emulate CLOCK_REALTIME using gettimeofday.

#16 Updated by Akira Tanaka 9 months ago

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

#17 Updated by Akira Tanaka 9 months ago

  • 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/DevelopersMeeting20130809

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

#18 Updated by Charles Nutter 7 months ago

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 clockgettime(CLOCKMONOTONIC). 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/9b0ca45cd756/src/os/linux/vm/os_linux.cpp 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::clockgettime API is called GETTIMEOFDAYBASEDCLOCKREALTIME.

So JRuby will always be able to support GETTIMEOFDAYBASEDCLOCKREALTIME via System.currentTimeMillis, CLOCKMONOTONIC 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.

#19 Updated by Charles Nutter 7 months ago

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/desktop/ms724397(v=vs.85).aspx

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 CLOCKMONOTONICRAW? 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/desktop/ms644904(v=vs.85).aspx

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.

#21 Updated by Akira Tanaka 7 months ago

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

#22 Updated by Yui NARUSE 7 months ago

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

Also available in: Atom PDF