util: add usec_add() which adds two usec_t values with overflow handling
authorLennart Poettering <lennart@poettering.net>
Mon, 1 Feb 2016 15:13:51 +0000 (16:13 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 1 Feb 2016 21:18:15 +0000 (22:18 +0100)
src/basic/time-util.h
src/test/test-time.c

index 7321e3c..b37d5ad 100644 (file)
@@ -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;
+}
index 8896b2c..ca44f81 100644 (file)
@@ -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;
 }