This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
timeval_subtract example
- From: "D. Hugh Redelmeier" <hugh at cs dot toronto dot edu>
- To: libc-help at sourceware dot org
- Date: Mon, 2 Feb 2015 22:57:01 -0500 (EST)
- Subject: timeval_subtract example
- Authentication-results: sourceware.org; auth=none
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?