-
-
Save diabloneo/9619917 to your computer and use it in GitHub Desktop.
#include <time.h> | |
void timespec_diff(struct timespec *start, struct timespec *stop, | |
struct timespec *result) | |
{ | |
if ((stop->tv_nsec - start->tv_nsec) < 0) { | |
result->tv_sec = stop->tv_sec - start->tv_sec - 1; | |
result->tv_nsec = stop->tv_nsec - start->tv_nsec + 1000000000; | |
} else { | |
result->tv_sec = stop->tv_sec - start->tv_sec; | |
result->tv_nsec = stop->tv_nsec - start->tv_nsec; | |
} | |
return; | |
} |
Should it be "1000000000UL" instead of "1000000000"?
This code is correct only if stop > start
. If start
is 0 and stop
is 1ns, then the code above will produce result->tv_sec = -1
and result->tv_nsec = 999999999
. If denormalized results are alright, then if ((stop->tv_nsec - start->tv_nsec) < 0)
is not necessary at all.
Should it be "1000000000UL" instead of "1000000000"?
It should be L
, not UL
, given that struct timespec::tv_nsec
is of type long
.
From man clock_gettime
:
The res and tp arguments are timespec structures, as specified in
<time.h>:
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
<sys/time.h> has a macro for calculating the difference of two timevals called timersub.
Modifying it for timespecs is straightforward.
// from <sys/time.h>
// used timersub macro, changed timeval to timespec
// kept the order of operands the same, that is a - b = result
# define timespec_diff_macro(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \
if ((result)->tv_nsec < 0) { \
--(result)->tv_sec; \
(result)->tv_nsec += 1000000000; \
} \
} while (0)
Or, as a function:
/**
* @fn timespec_diff(struct timespec *, struct timespec *, struct timespec *)
* @brief Compute the diff of two timespecs, that is a - b = result.
* @param a the minuend
* @param b the subtrahend
* @param result a - b
*/
static inline void timespec_diff(struct timespec *a, struct timespec *b,
struct timespec *result) {
result->tv_sec = a->tv_sec - b->tv_sec;
result->tv_nsec = a->tv_nsec - b->tv_nsec;
if (result->tv_nsec < 0) {
--result->tv_sec;
result->tv_nsec += 1000000000L;
}
}
<sys/time.h> has a macro for calculating the difference of two timevals called timersub.
Modifying it for timespecs is straightforward.
Thanks for that info. I just discovered that <sys/time.h>
also has timespecsub()
so you don't even need to modify it. It is a BSD function (actually a macro) and not a POSIX one. However, in linux we have libbsd to provide it.
The man pages includes many functions (or macros) which may also be interesting to you: man timespecsub
timerspecsub
nor timersub
are part of any standard.
timerspecsub
nortimersub
are part of any standard.
Yet they are useful, and relatively portable (Linux and BSDs).
Maybe
const struct timespec *start, const struct timespec *stop
?