So, let's see how std::chrono::steady_clock::now()
has been implemented in gcc. The answer can be found at https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/src/c%2B%2B11/chrono.cc
steady_clock::now() noexcept
{
#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
timespec tp;
// -EINVAL, -EFAULT
#ifdef _GLIBCXX_USE_CLOCK_GETTIME_SYSCALL
syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &tp);
#else
clock_gettime(CLOCK_MONOTONIC, &tp);
#endif
return time_point(duration(chrono::seconds(tp.tv_sec)
+ chrono::nanoseconds(tp.tv_nsec)));
#else
return time_point(system_clock::now().time_since_epoch());
#endif
}
from which one can infer that it delegates (or more precisely: can delegate) the job to C's standard function clock_gettime
.
Its manual page https://www.man7.org/linux/man-pages/man3/clock_gettime.3.html has a section "attributes", and there the value of "thread safety" is "MT-safe". This is explained here: https://www.man7.org/linux/man-pages/man7/attributes.7.html
Being MT-Safe does not imply a function is atomic, nor that it uses any of the memory synchronization mechanisms POSIX exposes to users.
In other words, you have no guarantees other that the function can be safely called in a multi-threaded environment.
At this point you can appreciate the fact that gcc/clang are open-source and see yourself what's inside clock_gettime
's implementation, as I did for steady_clock::now()
, but you'll never get such an answer for closed-source compilers, nor have a guarantee the implementation used by gcc/clang will never change.
But if you're after using a C++ clock in a lock-free algorithm, then you may be focusing on performance. Then, please read:
If your solution is to be multiplatform and essentially hardware-agnostic, then the penalty for using the clock may be similar to or even larger than that of using mutexes for synchronization. I don't know if this is the case, but this is certainly something you need to take into account.