Synopsis: When I was investigating the handling of the argument of clock_gettime (2)
in each language, I found such a strange sentence. Because of that, there is no description related to Windows. I may add it later.
clock_gettime
clock_gettime (2)
is an API for time acquisition standardized by the Single Unix Specification v2. For clock_gettime (2)
, the semantics and precision of time acquisition change depending on the constant passed to clock_id
.
To quote an example from a Linux man,
- CLOCK_REALTIME
A system-wide unique time that measures real time. Appropriate privileges are required to set this clock. This clock is a discontinuous change in system time(For example, if the system administrator manually changes the system time.)It is affected by the gradual adjustments made by, adjtime, and NTP.
CLOCK_REALTIME_COARSE (Linux 2.6.32 or later;Linux specific)
Fast but low accuracy CLOCK_REAL TIME. It is recommended to use when speed is very necessary and high-precision time stamp is not required.
CLOCK_MONOTONIC
A clock that cannot be set and is represented by a monotonically increasing time from a certain start point.(It is not specified when the start time will be).. This clock has discontinuous changes in system time(For example, if the system administrator manually changes the system time.)Not affected by, but adjtime(3)And are affected by the gradual adjustments made by NTP.
CLOCK_MONOTONIC_COARSE (Linux 2.6.32 or later;Linux specific)
Fast but low accuracy CLOCK_MONOTONIC. It is recommended to use when speed is very necessary and high-precision time stamp is not required.
CLOCK_MONOTONIC_RAW (Linux 2.6.28 or later;Linux specific)
CLOCK_Similar to MONOTONIC, but with NTP adjustments and adjtime(3)Provides hardware access to the raw time, unaffected by the gradual adjustments made by.
CLOCK_BOOTTIME (Linux 2.6.39 or later;Linux specific)
CLOCK_Same as MONOTONIC, except that it includes the time the system is suspended. With it, the application can also handle suspended states"monotonic"Clock can be obtained. Moreover, CLOCK_There is no need to perform complicated processing in REALTIME. CLOCK_In REALTIME, settimeofday(2)This is because if you change the time using, the time will change discontinuously.
a. This constant varies depending on the OS. Others, like sierra, have added a special API called clock_gettime_nsec_np
.
In this blog, the quoted part of the implementation was helpful. http://d.hatena.ne.jp/yohei-a/20140913/1410628229
Ruby
Process.clock_gettime
Ruby provides an API that calls clock_gettime (2)
directly. Specify clock_id
as an argument of Process.clock_gettime.
According to process.c, the following constants can be specified. It also describes which version was added properly, which is very wonderful. There was no specification for CLOCK_HIGHRES on Solaris. Also, Dragonfly BSD should be able to use the same options as FreeBSD, at least in the latest version, but wasn't mentioned.
* [CLOCK_REALTIME] SUSv2 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 2.1, macOS 10.12
* [CLOCK_MONOTONIC] SUSv3 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 3.4, macOS 10.12
* [CLOCK_PROCESS_CPUTIME_ID] SUSv3 to 4, Linux 2.5.63, OpenBSD 5.4, macOS 10.12
* [CLOCK_THREAD_CPUTIME_ID] SUSv3 to 4, Linux 2.5.63, FreeBSD 7.1, OpenBSD 5.4, macOS 10.12
* [CLOCK_VIRTUAL] FreeBSD 3.0, OpenBSD 2.1
* [CLOCK_PROF] FreeBSD 3.0, OpenBSD 2.1
* [CLOCK_REALTIME_FAST] FreeBSD 8.1
* [CLOCK_REALTIME_PRECISE] FreeBSD 8.1
* [CLOCK_REALTIME_COARSE] Linux 2.6.32
* [CLOCK_REALTIME_ALARM] Linux 3.0
* [CLOCK_MONOTONIC_FAST] FreeBSD 8.1
* [CLOCK_MONOTONIC_PRECISE] FreeBSD 8.1
* [CLOCK_MONOTONIC_COARSE] Linux 2.6.32
* [CLOCK_MONOTONIC_RAW] Linux 2.6.28, macOS 10.12
* [CLOCK_MONOTONIC_RAW_APPROX] macOS 10.12
* [CLOCK_BOOTTIME] Linux 2.6.39
* [CLOCK_BOOTTIME_ALARM] Linux 3.0
* [CLOCK_UPTIME] FreeBSD 7.0, OpenBSD 5.5
* [CLOCK_UPTIME_FAST] FreeBSD 8.1
* [CLOCK_UPTIME_RAW] macOS 10.12
* [CLOCK_UPTIME_RAW_APPROX] macOS 10.12
* [CLOCK_UPTIME_PRECISE] FreeBSD 8.1
* [CLOCK_SECOND] FreeBSD 8.1
Time.now
The most commonly used current time, which is called Time.now
or Time # initialize
, is fixed to CLOCK_REALTIME
if clock_gettime is defined. If not, I'm using gettimeofday (macOS, etc.).
Although it is not written in Document, if clock_gettime / gettimeofday fails internally, rb_sys_fail Throw an exception with
.
time.clock_gettime
In Python 3.3 and later, you can call clock_gettime (2)
directly with time.clock_gettime (clock_id)
like Ruby. However, what can be passed to clock_id is and documented, and apparently constants such as CLOCK_MONOTONIC_COARSE
cannot be passed (as of 3.6.0). In the first place, Python doesn't seem to provide an API that uses CLOCK_MONOTONIC_COARSE
internally or passes it from the outside.
Looking at pytime.c, the pymonotonic function is fixed to CLOCK_MONOTONIC
, and the pygettimeofday function is used to fix CLOCK_REALTIME
. In pymonotonic, mach_absolute_time
is passed for macOS and CLOCK_HIGHRES
is passed for Solaris.
time.time
The most commonly used time.time ()
internally calls the pygetimeofday
function, which is equivalent totime.clock_gettime (CLOCK_REALTIME)
. Like Time.now in Ruby, gettimeofday (2) is used as the fallback destination.
If the system call call fails, it returns NULL internally, but I'm not sure.
pep418
This is the clock-based proposal PEP newly added to the time module in Python 3.3 https://www.python.org/dev/peps/pep-0418/
Perl5
Is it attached to the main body? The Time :: HiRes module that is doing seems to be the de facto.
clock_gettime
You can pass CLOCK_MONOTONIC
or CLOCK_REALTIME
to clock_gettime
. Like Ruby and Python, clock_gettime does not grow if it is not defined on the OS side, so there is no mechanism to fall back to gettimofday (2). At the moment, it does not support the API newly created in the latest macOS Sierra, but FreeBSD's CLOCK_MONOTONIC_FAST
etc. are defined as constants.
time
The time function internally calls gettimeofday (2). It seems to return -1.0 if the call to gettimeofday (2) fails. When I wondered what this meant, I wondered if the failure status of the system call was expressed as a float. There are no direct sum types, direct product types, or exceptions in Perl, so it would be better to express the return values in a mixed manner.
It became annoying, so it became messy.
C++
Look at std :: chrono (libstdc ++-v3 / src / c ++ 11 / chrono.cc) in STL.
std::chrono::system_clock::now
CLOCK_REALTIME
if you have clock_gettime (2)std::chrono::steady_clock::now
CLOCK_MONOTONIC
if you have clock_gettime (2)It has become.
Go
Many platforms (Linux, FreeBSD, OpenBSD) use CLOCK_REALTIME
to implement now
and CLOCK_MONOTONIC
to implement nanotime
for each architecture. For NetBSD and Solaris, CLOCK_REALTIME
is also used to implement nanotime, but I'm not sure. I'm not sure about Plan9.
The situation is complicated on macOS, probably because it is a statically linked binary. But I'm not sure. Keep only the URL that was referenced. https://opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/i386/cpu_capabilities.h
FreeBSD says that you can use CLOCK_MONOTONIC_FAST
if you turn off 8-STABLE support, but Linux does not say that you can use CLOCK_MONOTONIC_COARSE
if you turn off support before 2.6.32.
// func now() (sec int64, nsec int32)
TEXT time·now(SB), NOSPLIT, $32
MOVL $232, AX // clock_gettime
MOVQ $0, DI // CLOCK_REALTIME
LEAQ 8(SP), SI
SYSCALL
MOVQ 8(SP), AX // sec
MOVQ 16(SP), DX // nsec
// sec is in AX, nsec in DX
MOVQ AX, sec+0(FP)
MOVL DX, nsec+8(FP)
RET
TEXT runtime·nanotime(SB), NOSPLIT, $32
MOVL $232, AX
// We can use CLOCK_MONOTONIC_FAST here when we drop
// support for FreeBSD 8-STABLE.
MOVQ $4, DI // CLOCK_MONOTONIC
LEAQ 8(SP), SI
SYSCALL
MOVQ 8(SP), AX // sec
MOVQ 16(SP), DX // nsec
// sec is in AX, nsec in DX
// return nsec in AX
IMULQ $1000000000, AX
ADDQ DX, AX
MOVQ AX, ret+0(FP)
RET
Rust
In the standard library std :: time, ʻInstant :: now is fixed to
CLOCK_MONOTONICand
SystemTime :: now is fixed to
CLOCK_REALTIMEon many platforms. For macOS, we use
mach_absolute_time /
gettimeofdayrespectively. From the comments in the Ruby source,
CLOCK_MONOTONIC` should work fine on Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 3.4 (and for some unknown reason, the recent Dragonfly BSD). Panic if system call call fails.
Instant::now
mach_absolute_time (macOS/iOS)
CLOCK_MONOTONIC (Linux/Android)
SystemTime::now
gettimeofday (macOS/iOS)
CLOCK_REALTIME (Linux/Android)
rust-coarsetime crate
If you want speed over accuracy, you can use rust-coarsetime. rust-coarsetime uses CLOCK_MONOTONIC_COARSE
/ CLOCK_MONOTONIC_RAW_APPROX
/ CLOCK_MONOTONIC_FAST
on Linux / OSX / FreeBSD (DragonflyBSD) respectively.
There is Clock.currTime
/ Clock.currStdTime
in std.datetime of the standard library Phobos as API of time acquisition, and ClockType can be specified. Both internally call the currStdTime function. Throws a TimeException exception if the system call call fails.
The implementation of currStdTime by specifying ClockType for each OS is summarized in the table below. OSs that don't have Sierra's new API support or aren't on the branch here (eg OpenBSD) die as Unsupported OS at compile time.
Here, time (2) / gettimeofday (2) each represent a system call, and the constant-like one is the constant passed to the argument of clock_gettime (2).
time(2) (Linux)
time(2) (OSX)
CLOCK_SECOND (FreeBSD 8.1)
time(2) (NetBSD)
time(2) (Solaris)
CLOCK_REALTIME_COARSE (Linux 2.6.32)
gettimeofday(2) (OSX)
CLOCK_REALTIME_FAST (FreeBSD 8.1)
gettimeofday(2) (NetBSD)
CLOCK_REALTIME (Solaris)
CLOCK_REALTIME (Linux 2.5.63)
gettimeofday(2) (OSX)
CLOCK_REALTIME (FreeBSD 3.0)
gettimeofday(2) (NetBSD)
CLOCK_REALTIME (Solaris)
CLOCK_REALTIME (Linux 2.5.63)
gettimeofday(2) (OSX)
CLOCK_REALTIME_PRECISE (FreeBSD 8.1)
gettimeofday(2) (NetBSD)
CLOCK_REALTIME (Solaris)
Recommended Posts