I need to handle timeout scenarios in code and want to use clock_gettime(CLOCK_MONOTONIC)
if the system supports Monotonic Clock.
#ifdef CLOCK_MONOTONIC
clock_gettime(CLOCK_MONOTONIC, & spec);
#else
clock_gettime(CLOCK_REALTIME, & spec);
#endif
I'm not sure if this is enough. That's to say, is it possible that the system defines CLOCK_MONOTONIC
by it does not really support monotonic clock? Or what's the reliable way to check if monotonic clock is supported?
A monotonic clock is a time source that won't ever jump forward or backward (due to NTP or Daylight Savings Time updates).
So measuring a duration from the wall-clock can be biased. The second clock is called the monotonic-clock. Here, we have a guarantee that the time always moves forward and will not be impacted by variations leading to jumps in time.
nanoTime() is monotonic (if the underlying system supports it). So, if I want to base my code on the java. time API, I would need Clock that uses nanoTime internally to ensure one-way flow of the time.
Per the letter of POSIX, you may in fact need a runtime test even if the constant CLOCK_MONOTONIC
is defined. The official way to handle this is with the _POSIX_MONOTONIC_CLOCK
"feature-test macro", but those macros have really complicated semantics: quoting http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/unistd.h.html ,
If a symbolic constant is not defined or is defined with the value -1, the option is not supported for compilation. If it is defined with a value greater than zero, the option shall always be supported when the application is executed. If it is defined with the value zero, the option shall be supported for compilation and might or might not be supported at runtime.
Translating that three-way distinction into code would give you something like this:
#if !defined _POSIX_MONOTONIC_CLOCK || _POSIX_MONOTONIC_CLOCK < 0
clock_gettime(CLOCK_REALTIME, &spec);
#elif _POSIX_MONOTONIC_CLOCK > 0
clock_gettime(CLOCK_MONOTONIC, &spec);
#else
if (clock_gettime(CLOCK_MONOTONIC, &spec))
clock_gettime(CLOCK_REALTIME, &spec));
#endif
But it's simpler and more readable if you just always do the runtime test when CLOCK_MONOTONIC itself is defined:
#ifdef CLOCK_MONOTONIC
if (clock_gettime(CLOCK_MONOTONIC, &spec))
#endif
clock_gettime(CLOCK_REALTIME, &spec);
This increases the size of your code by some trivial amount on current-generation OSes that do support CLOCK_MONOTONIC
, but the readability benefits are worth it in my opinion.
There is also a pretty strong argument for using CLOCK_MONOTONIC
unconditionally; you're more likely to find an OS that doesn't support clock_gettime
at all (e.g. MacOS X still doesn't have it as far as I know) than an OS that has clock_gettime
but not CLOCK_MONOTONIC
.
POSIX only requires that CLOCK_REALTIME
be present, other clocks are optional.
If the monotonic clock is available, the macro _POSIX_MONOTONIC_CLOCK
will be defined in unistd.h
(according to the Availability section of the man page)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With