Skip to content

Commit

Permalink
lib: time-util: Fix timeval_cmp_margin() to correctly handle a margin…
Browse files Browse the repository at this point in the history
… crossing the second boundary.

The timeval_cmp_margin() function incorrectly assumed that the margin is
irrelevent when the tv_sec values are different.
  • Loading branch information
stephanbosch authored and mrannanj committed Feb 7, 2018
1 parent 7dc18d3 commit a2577af
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 10 deletions.
138 changes: 138 additions & 0 deletions src/lib/test-time-util.c
Expand Up @@ -54,6 +54,143 @@ static void test_timeval_cmp(void)
test_end();
}

static void test_timeval_cmp_margin(void)
{
static const struct {
struct timeval tv1, tv2;
unsigned int margin;
int output;
} tests[] = {
{
.tv1 = { 0, 0 },
.tv2 = { 0, 0 },
.output = 0,
},{
.tv1 = { INT_MAX, 999999 },
.tv2 = { INT_MAX, 999999 },
.output = 0,

},{
.tv1 = { 0, 0 },
.tv2 = { 0, 1 },
.output = -1,
},{
.tv1 = { 0, 0 },
.tv2 = { 1, 0 },
.output = -1,
},{
.tv1 = { 0, 999999 },
.tv2 = { 1, 0 },
.output = -1,
},{
.tv1 = { 1, 0 },
.tv2 = { 1, 1 },
.output = -1,
},{
.tv1 = { -INT_MAX, 0 },
.tv2 = { INT_MAX, 0 },
.output = -1,
},{
.tv1 = { 0, 999999 },
.tv2 = { 1, 0 },
.margin = 1,
.output = 0,
},{
.tv1 = { 1, 0 },
.tv2 = { 1, 1 },
.margin = 1,
.output = 0,
},{
.tv1 = { 0, 999998 },
.tv2 = { 1, 0 },
.margin = 1,
.output = -1,
},{
.tv1 = { 1, 0 },
.tv2 = { 1, 2 },
.margin = 1,
.output = -1,
},{
.tv1 = { 0, 998000 },
.tv2 = { 1, 0 },
.margin = 2000,
.output = 0,
},{
.tv1 = { 1, 0 },
.tv2 = { 1, 2000 },
.margin = 2000,
.output = 0,
},{
.tv1 = { 0, 997999 },
.tv2 = { 1, 0 },
.margin = 2000,
.output = -1,
},{
.tv1 = { 1, 0 },
.tv2 = { 1, 2001 },
.margin = 2000,
.output = -1,
},{
.tv1 = { 0, 1 },
.tv2 = { 1, 0 },
.margin = 999999,
.output = 0,
},{
.tv1 = { 1, 0 },
.tv2 = { 1, 999999 },
.margin = 999999,
.output = 0,
},{
.tv1 = { 0, 0 },
.tv2 = { 1, 0 },
.margin = 999999,
.output = -1,
},{
.tv1 = { 1, 0 },
.tv2 = { 2, 0 },
.margin = 999999,
.output = -1,
},{
.tv1 = { 10, 0 },
.tv2 = { 11, 500000 },
.margin = 1500000,
.output = 0,
},{
.tv1 = { 8, 500000 },
.tv2 = { 10, 0 },
.margin = 1500000,
.output = 0,
},{
.tv1 = { 10, 0 },
.tv2 = { 11, 500001 },
.margin = 1500000,
.output = -1,
},{
.tv1 = { 8, 499999 },
.tv2 = { 10, 0 },
.margin = 1500000,
.output = -1,
},{
.tv1 = { 1517925358, 999989 },
.tv2 = { 1517925359, 753 },
.margin = 2000,
.output = 0,
}
};
unsigned int i;

test_begin("timeval_cmp_margin()");
for (i = 0; i < N_ELEMENTS(tests); i++) {
const struct timeval *tv1 = &tests[i].tv1, *tv2 = &tests[i].tv2;
unsigned int margin = tests[i].margin;
int output = tests[i].output;

test_assert(timeval_cmp_margin(tv1, tv2, margin) == output);
test_assert(timeval_cmp_margin(tv2, tv1, margin) == -output);
}
test_end();
}

static void test_timeval_diff(void)
{
static const struct timeval input[] = {
Expand Down Expand Up @@ -201,6 +338,7 @@ static void test_strftime_fixed(void)
void test_time_util(void)
{
test_timeval_cmp();
test_timeval_cmp_margin();
test_timeval_diff();
test_time_to_local_day_start();
test_strftime_now();
Expand Down
35 changes: 25 additions & 10 deletions src/lib/time-util.c
Expand Up @@ -23,16 +23,31 @@ int timeval_cmp(const struct timeval *tv1, const struct timeval *tv2)
int timeval_cmp_margin(const struct timeval *tv1, const struct timeval *tv2,
unsigned int usec_margin)
{
if (tv1->tv_sec < tv2->tv_sec)
return -1;
if (tv1->tv_sec > tv2->tv_sec)
return 1;

if ((tv2->tv_usec - tv1->tv_usec) > (int)usec_margin)
return -1;
if ((tv1->tv_usec - tv2->tv_usec) > (int)usec_margin)
return 1;
return 0;
unsigned long long usecs_diff;
int sec_margin, ret;

if (tv1->tv_sec < tv2->tv_sec) {
sec_margin = ((int)usec_margin / 1000000) + 1;
if ((tv2->tv_sec - tv1->tv_sec) > sec_margin)
return -1;
usecs_diff = (tv2->tv_sec - tv1->tv_sec) * 1000000ULL +
(tv2->tv_usec - tv1->tv_usec);
ret = -1;
} else if (tv1->tv_sec > tv2->tv_sec) {
sec_margin = ((int)usec_margin / 1000000) + 1;
if ((tv1->tv_sec - tv2->tv_sec) > sec_margin)
return 1;
usecs_diff = (tv1->tv_sec - tv2->tv_sec) * 1000000ULL +
(tv1->tv_usec - tv2->tv_usec);
ret = 1;
} else if (tv1->tv_usec < tv2->tv_usec) {
usecs_diff = tv2->tv_usec - tv1->tv_usec;
ret = -1;
} else {
usecs_diff = tv1->tv_usec - tv2->tv_usec;
ret = 1;
}
return usecs_diff > usec_margin ? ret : 0;
}

int timeval_diff_msecs(const struct timeval *tv1, const struct timeval *tv2)
Expand Down

0 comments on commit a2577af

Please sign in to comment.