I have a function that uses difftime to detect the time in seconds since the communication heartbeat has stopped. This function could run as fast as every 50 milliseconds. The
difftime()
is of use on systems where time_t
supports time to a higher resolution than integral seconds. Although allowed, I've never encountered such a system - I don't imagine one exists. On POSIX systems specifically, time_t
is measured in integral seconds, and difftime()
is equivalent to arithmetic subtraction of its arguments, so in fact you are better off simply using:
commlost_secs_cur += current_time - previous_time ;
That said, your implementation is somewhat over-complex, rather than accumulating time since the previous call, which may be smaller than the clock resolution, you could simply time-stamp the last heartbeat observed and return time since then:
int commlost(uint16_t heartbeat_read_cur)
{
time_t current_time = time(0) ;
static time_t heartbeat_timestamp = 0 ;
static uint16_t heartbeat_read_prev ;
// If first time, or heartbeat changed...
if( heartbeat_timestamp == 0 || heartbeat_read_prev != heartbeat_read_cur)
{
// ... timestamp heartbeat
heartbeat_timestamp = time(0) ;
// ... keep last heartbeat
heartbeat_read_prev = heartbeat_read_cur ;
}
// Return seconds since last heartbeat timestamp
return current_time - heartbeat_timestamp ;
}
I am not sure why you would use uint16_t
for this; there is little or no advantage unless it is for compatibility with some specific protocol or file format.
Before querying time, read the time(7) man page (and read it again).
The, I suggest using clock_gettime(2) with e.g. CLOCK_MONOTONIC
or CLOCK_REALTIME
, and preferably use double
for time calculations (since a struct timespec
is generally larger than any integral type).
Don't use uint16_t
for such time calculations.
Try using
inline double double_gettime (clockid_t cid) {
struct timespec ts = {0,0};
clock_gettime(cid, &ts);
return (double)ts.tv_sec + 1.0e-9*ts.tv_nsec;
}
You might want to make that function fancier, by testing if clock_gettime
is failing and giving NAN
when it fails! This is left as an exercise to the reader. You could also, for CLOCK_REALTIME
etc, measure the difference between some time at start of process and the current time (i.e. compute a struct timespec
of differences and convert that difference to a double
)
Then things like
double tstart = double_gettime(CLOCK_REALTIME);
some_long_computation();
double tend = double_gettime(CLOCK_REALTIME);
printf ("needed %f seconds to compute\n", tend-tstart);
See also clock(3)