patterncModerate
Correctness of calculations with struct timespec
Viewed 0 times
structwithcorrectnesscalculationstimespec
Problem
I've noticed some discrepancies in timings in our system, and I'm trying to narrow down what could be causing them.
I'm reviewing out time abstraction, and as far as I can determine it's fine.
Am I missing anything, and is it portable (besides being constrained to POSIX)?
I'm reviewing out time abstraction, and as far as I can determine it's fine.
Am I missing anything, and is it portable (besides being constrained to POSIX)?
typedef struct timespec Time;
static inline Time getTime() {
static struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return time;
}
static inline __constant Time timeAdd(Time oldTime, Time time) {
if (time.tv_nsec + oldTime.tv_nsec >= 1E9)
return (Time){
tv_sec: time.tv_sec + oldTime.tv_sec + 1,
tv_nsec: time.tv_nsec + oldTime.tv_nsec - 1E9
};
else
return (Time){
tv_sec: time.tv_sec + oldTime.tv_sec,
tv_nsec: time.tv_nsec + oldTime.tv_nsec
};
}
static inline __constant Time timeDiff(Time oldTime, Time time) {
if (time.tv_nsec < oldTime.tv_nsec)
return (Time){
tv_sec: time.tv_sec - 1 - oldTime.tv_sec,
tv_nsec: 1E9 + time.tv_nsec - oldTime.tv_nsec
};
else
return (Time){
tv_sec: time.tv_sec - oldTime.tv_sec,
tv_nsec: time.tv_nsec - oldTime.tv_nsec
};
}
static __always_inline __constant double timeSeconds(Time time) {
return time.tv_sec + time.tv_nsec/1E9;
}
static inline double timeSince(Time oldTime) {
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return timeSeconds(timeDiff(oldTime, time));
}Solution
I can see nothing wrong, but I think it is not optimal. My compiler warns me
about floating point conversions of those '1E9' constants. If I rewrite your
significantly smaller:
The same goes for the other functions, I think.
about floating point conversions of those '1E9' constants. If I rewrite your
timeAdd as follows, the code is easier to read and the generated code issignificantly smaller:
#define BILLION 1000000000
Time timeAdd(Time t1, Time t2)
{
long sec = t2.tv_sec + t1.tv_sec;
long nsec = t2.tv_nsec + t1.tv_nsec;
if (nsec >= BILLION) {
nsec -= BILLION;
sec++;
}
return (Time){ .tv_sec = sec, .tv_nsec = nsec };
}The same goes for the other functions, I think.
Code Snippets
#define BILLION 1000000000
Time timeAdd(Time t1, Time t2)
{
long sec = t2.tv_sec + t1.tv_sec;
long nsec = t2.tv_nsec + t1.tv_nsec;
if (nsec >= BILLION) {
nsec -= BILLION;
sec++;
}
return (Time){ .tv_sec = sec, .tv_nsec = nsec };
}Context
StackExchange Code Review Q#40176, answer score: 11
Revisions (0)
No revisions yet.