-
-
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.
timerspecsubnortimersubare part of any standard.
Yet they are useful, and relatively portable (Linux and BSDs).
Maybe
const struct timespec *start, const struct timespec *stop?