A very simple stopwatch. Intended to be used for simple benchmarking when you want to do a task several times, but exclude some setup code from the benchmarking.
Some things I have already considered:
Using the
restrictkeyword. I think it's overkill for this simple project.Adding error checking in case you start a non-initialized (reset) clock. I left this responsibility to the user.
Error checking in general. Don't pass uninitialized pointers.
Returning the return value of
gettimeofdayinstartandstop. Very few people would use this.Returning
swinstart,stopandreset. Chaining does not seem very useful here.Removing the chaining in
stop. Basically just added it to motivate the return values fortimeDiffandtimeAdd, even if I think it looks ugly. :)
#include <sys/time.h>
#include <unistd.h>
struct timeval *timeDiff(struct timeval *out,
const struct timeval *a,
const struct timeval *b)
{
*out = (struct timeval) { .tv_sec = a->tv_sec - b->tv_sec,
.tv_usec = a->tv_usec - b->tv_usec };
return out;
}
struct timeval *timeAdd(struct timeval *out,
const struct timeval *a,
const struct timeval *b)
{
*out = (struct timeval) { .tv_sec = a->tv_sec + b->tv_sec,
.tv_usec = a->tv_usec + b->tv_usec };
return out;
}
struct stopwatch {
struct timeval soFar;
struct timeval start;
};
void reset(struct stopwatch *sw) {
sw->soFar = sw->start = (struct timeval) {0, 0};
}
void start(struct stopwatch *sw) {
gettimeofday(&sw->start, NULL);
}
void stop(struct stopwatch *sw) {
struct timeval now;
gettimeofday(&now, NULL);
struct timeval diff;
timeAdd(&sw->soFar, timeDiff(&diff, &now, &sw->start), &sw->soFar);
}
And here is some code if you want to try it out, but it's not intended to be a part of the review.
#include <stdio.h>
double sec(const struct stopwatch *sw) {
const double M = 1000000;
return (sw->soFar.tv_sec * M + sw->soFar.tv_usec)/M;
}
int main(void)
{
struct stopwatch sw;
reset(&sw);
start(&sw);
sleep(3.97);
stop(&sw);
printf("%f\n", sec(&sw));
start(&sw);
sleep(1);
stop(&sw);
printf("%f\n", sec(&sw));
reset(&sw);
start(&sw);
sleep(1);
stop(&sw);
printf("%f\n", sec(&sw));
}