This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

timeval_subtract example


I'm trying to think about arithmetic with time values (struct timeval or
struct timespec).

In the glibc manual, section 21.2, there is a function to subtract two
struct timevals, "timeval_subtract".
<https://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html>

/* Subtract the âstruct timevalâ values X and Y,
   storing the result in RESULT.
   Return 1 if the difference is negative, otherwise 0. */

int
timeval_subtract (result, x, y)
     struct timeval *result, *x, *y;
{
  /* Perform the carry for the later subtraction by updating 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;
  }

  /* Compute the time remaining to wait.
     tv_usec is certainly positive. */
  result->tv_sec = x->tv_sec - y->tv_sec;
  result->tv_usec = x->tv_usec - y->tv_usec;

  /* Return 1 if result is negative. */
  return x->tv_sec < y->tv_sec;
}

Even though it apparently has two input structs and an output struct, it
can actually modify one of the input structs (*y).  This seems like bad
style.

POSIX says that the type of tv_usec is suseconds_t.  That type must be
able to represent integers in the range -1 through 1000000.

When can tv_usec be 1000000?  I don't see how POSIX functions can
generate this value.

When can tv_usec be -1?  I don't see how POSIX functions can generate
this value.

If x->tv_usec is -1 and y->tv_usec is 1000000 then the subexpression
	y->tv_usec - x->tv_usec
might overflow (in the sense that the type not allow the value
1000001).  I admit that this is being very pedantic.

The next line also takes y->tv_usec out of its allowable range
	y->tv_usec -= 1000000 * nsec;

POSIX says that tv_sec is of type time_t.  So we know that it is
signed and any representable positive value has a representable
negation.  But that isn't true of tv_usec.

Should negative durations be representable?  What then is the
representation of the tv_usec portion?  Is it a positive offset from
the negative tv_sec?  Or is it an increase of the magnitude of
tv_usec?  Can anything be inferred from POSIX?

The BSD functions that are described on timeradd(3) on my Fedora
system seem to promise results with tv_usec in the range 0 through
999999.

I would expect more of the parameters to be of "const struct timeval
*" type (none are).  Is there a reason?

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]