3

I need to use gettimeofday to measure time differences in microsecond resolution using this function.

I know this is not the best function, but I want to understand why. In this question AndrewStone says there'll be a problem twice a yea, I don't understand why would there be a problem if we're just counting microseconds from epoch.

And if I misunderstood the man and the time is the value of the seconds + the microseconds how can I solve this issue?

Community
  • 1
  • 1
Darius
  • 707
  • 6
  • 21
  • AndrewStone just didn't know what he was talking about. However using the monotonic clock for measuring intervals is a good practice if you want to avoid errors caused by manual clock adjustments or a badly-behaved ntpd (a good ntpd will always make the adjustments continuously so they don't disturb anything). – R.. GitHub STOP HELPING ICE Feb 24 '14 at 16:47

1 Answers1

4

gettimeofday takes two arguments:

int gettimeofday(struct timeval *tv, struct timezone *tz);

As per the man page:

The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL.

Provided you do this, it will simply return seconds and microseconds since the epoch, i.e. no timezones are involved. Whoever told you differently is wrong in this respect.

However, you still have to be a little careful. Whilst you won't see this advance or retard by an hour, I believe you will find that it advances and retards as wall time is adjusted by things like ntp. So the elapsed number of microseconds between two calls may not be the difference between the two results (if, for instance, ntp is advancing or retarding the clock).

A better route is to use clock_gettime() with CLOCK_REALTIME or CLOCK_MONOTONIC, depending on exactly what you are trying to measure (elapsed time or change in clock).

Edit: you wanted a routine to subtract two timeval structures. Here's one:

int
timeval_subtract (struct timeval *result, struct timeval *x,
                  struct timeval *y)
{
  if (x->tv_usec < y->tv_usec)
    {
      int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
      y->tv_usec -= 1000000 * nsec;
      y->tv_sec += nsec;
    }

  if (x->tv_usec - y->tv_usec > 1000000)
    {
      int nsec = (x->tv_usec - y->tv_usec) / 1000000;
      y->tv_usec += 1000000 * nsec;
      y->tv_sec -= nsec;
    }

  result->tv_sec = x->tv_sec - y->tv_sec;
  result->tv_usec = x->tv_usec - y->tv_usec;

  return x->tv_sec < y->tv_sec;
}

which is similar to the one here: http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html

abligh
  • 24,573
  • 4
  • 47
  • 84
  • Sorry for being a bit slow, but do you say that each member of timeval holds the same value but with different resolution or that I should convert the seconds into microseconds and add them? And there're no potential problems if an even is beginning at 31.12.14 23:59:59 and ending in 2015? – Darius Feb 24 '14 at 14:25
  • No I did not say either of those things. `timeval` holds seconds and microseconds (same for both calls, obviously) and you will need to write a small routine to subtract one from the other (I'll include one for you in a second in the post). I've told you what the potential problems are (that wall time may be skewed by ntp etc.) and also the correct way to fix them (`clock_gettime`). However, change in daylight saving is *not* a problem if you pass the `tz` argument to `gettimeofday` as `NULL`. – abligh Feb 24 '14 at 14:28
  • Thank you so much. One last thing, there's no danger of wrongly counting time at the end of the year? – Darius Feb 24 '14 at 14:37
  • There is nothing special that happens to the result of `gettimeofday` at the end of the year, save for the fact that this is traditionally when leap seconds are introduced/removed, which would fall within the danger of 'adjustment' as I set out above. – abligh Feb 24 '14 at 14:44