diff options
-rw-r--r-- | src/basic/time-util.h | 13 | ||||
-rw-r--r-- | src/test/test-time.c | 15 |
2 files changed, 26 insertions, 2 deletions
diff --git a/src/basic/time-util.h b/src/basic/time-util.h index 7321e3c670..b37d5ad5dc 100644 --- a/src/basic/time-util.h +++ b/src/basic/time-util.h @@ -127,3 +127,16 @@ time_t mktime_or_timegm(struct tm *tm, bool utc); struct tm *localtime_or_gmtime_r(const time_t *t, struct tm *tm, bool utc); unsigned long usec_to_jiffies(usec_t usec); + +static inline usec_t usec_add(usec_t a, usec_t b) { + usec_t c; + + /* Adds two time values, and makes sure USEC_INFINITY as input results as USEC_INFINITY in output, and doesn't + * overflow. */ + + c = a + b; + if (c < a || c < b) /* overflow check */ + return USEC_INFINITY; + + return c; +} diff --git a/src/test/test-time.c b/src/test/test-time.c index 8896b2c92b..ca44f81f9c 100644 --- a/src/test/test-time.c +++ b/src/test/test-time.c @@ -176,9 +176,19 @@ static void test_get_timezones(void) { r = get_timezones(&zones); assert_se(r == 0); - STRV_FOREACH(zone, zones) { + STRV_FOREACH(zone, zones) assert_se(timezone_is_valid(*zone)); - } +} + +static void test_usec_add(void) { + assert_se(usec_add(0, 0) == 0); + assert_se(usec_add(1, 4) == 5); + assert_se(usec_add(USEC_INFINITY, 5) == USEC_INFINITY); + assert_se(usec_add(5, USEC_INFINITY) == USEC_INFINITY); + assert_se(usec_add(USEC_INFINITY-5, 2) == USEC_INFINITY-3); + assert_se(usec_add(USEC_INFINITY-2, 2) == USEC_INFINITY); + assert_se(usec_add(USEC_INFINITY-1, 2) == USEC_INFINITY); + assert_se(usec_add(USEC_INFINITY, 2) == USEC_INFINITY); } int main(int argc, char *argv[]) { @@ -190,6 +200,7 @@ int main(int argc, char *argv[]) { test_format_timespan(USEC_PER_SEC); test_timezone_is_valid(); test_get_timezones(); + test_usec_add(); return 0; } |