* [LTP] [COMMITTED] [PATCH 1/2] tst_timer.h: Add timeval helpers
@ 2017-06-13 16:00 Cyril Hrubis
2017-06-13 16:00 ` [LTP] [RFC] [PATCH 2/2] tst_timer.h: Make time conversions saturated Cyril Hrubis
0 siblings, 1 reply; 6+ messages in thread
From: Cyril Hrubis @ 2017-06-13 16:00 UTC (permalink / raw)
To: ltp
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
include/tst_timer.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/include/tst_timer.h b/include/tst_timer.h
index f0a10bd45..f294b0eb7 100644
--- a/include/tst_timer.h
+++ b/include/tst_timer.h
@@ -51,6 +51,22 @@ static inline long long tst_timespec_to_ms(struct timespec t)
}
/*
+ * Converts timeval to microseconds.
+ */
+static inline long long tst_timeval_to_us(struct timeval t)
+{
+ return t.tv_sec * 1000000 + t.tv_usec;
+}
+
+/*
+ * Converts timeval to miliseconds.
+ */
+static inline long long tst_timeval_to_ms(struct timeval t)
+{
+ return t.tv_sec * 1000 + (t.tv_usec + 500) / 1000;
+}
+
+/*
* Converts ms to struct timeval
*/
static inline struct timeval tst_ms_to_timeval(long long ms)
@@ -137,6 +153,38 @@ static inline long long tst_timespec_diff_ms(struct timespec t1,
}
/*
+ * Returns difference between two timeval structures.
+ */
+static inline struct timeval tst_timeval_diff(struct timeval t1,
+ struct timeval t2)
+{
+ struct timeval res;
+
+ res.tv_sec = t1.tv_sec - t2.tv_sec;
+
+ if (t1.tv_usec < t2.tv_usec) {
+ res.tv_sec--;
+ res.tv_usec = 1000000 - (t2.tv_usec - t1.tv_usec);
+ } else {
+ res.tv_usec = t1.tv_usec - t2.tv_usec;
+ }
+
+ return res;
+}
+
+static inline long long tst_timeval_diff_us(struct timeval t1,
+ struct timeval t2)
+{
+ return tst_timeval_to_us(tst_timeval_diff(t1, t2));
+}
+
+static inline long long tst_timeval_diff_ms(struct timeval t1,
+ struct timeval t2)
+{
+ return tst_timeval_to_ms(tst_timeval_diff(t1, t2));
+}
+
+/*
* Returns absolute value of difference between two timespec structures.
*/
static inline struct timespec tst_timespec_abs_diff(struct timespec t1,
--
2.13.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [LTP] [RFC] [PATCH 2/2] tst_timer.h: Make time conversions saturated
2017-06-13 16:00 [LTP] [COMMITTED] [PATCH 1/2] tst_timer.h: Add timeval helpers Cyril Hrubis
@ 2017-06-13 16:00 ` Cyril Hrubis
2017-06-14 14:47 ` Jan Stancek
0 siblings, 1 reply; 6+ messages in thread
From: Cyril Hrubis @ 2017-06-13 16:00 UTC (permalink / raw)
To: ltp
The conversions of struct timeval and struct timespec to us and ms are
now saturated so instead of overflowing/underflowing long long these
return LLONG_MAX/LLONG_MIN.
This commit also adds tst_us_to_timespec(), tst_ms_to_timespec() and
newlib_tests/tst_timer test to assert that the saturated conversion
actually works.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
include/tst_timer.h | 129 ++++++++++++++++++++++++++++++++++++++++---
lib/newlib_tests/.gitignore | 1 +
lib/newlib_tests/tst_timer.c | 126 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 248 insertions(+), 8 deletions(-)
create mode 100644 lib/newlib_tests/tst_timer.c
diff --git a/include/tst_timer.h b/include/tst_timer.h
index f294b0eb7..b1f595bd4 100644
--- a/include/tst_timer.h
+++ b/include/tst_timer.h
@@ -33,37 +33,124 @@
#include <sys/time.h>
#include <time.h>
+#include <limits.h>
+
+#define LLONG_MAX_USEC_OVERFLOW(sec, usec) \
+ (sizeof(time_t) == 8 && ((sec == LLONG_MAX/1000000 && usec > LLONG_MAX%1000000) \
+ || (sec > LLONG_MAX/1000000)))
+
+#define LLONG_MIN_USEC_UNDERFLOW(sec, usec) \
+ ((sec == LLONG_MIN/1000000 && usec < LLONG_MIN%1000000) \
+ || (sec < LLONG_MIN/1000000))
+
+#define LLONG_MAX_MSEC_OVERFLOW(sec, msec) \
+ ((sec == LLONG_MAX/1000 && msec > LLONG_MAX%1000) \
+ || (sec > LLONG_MAX/1000))
+
+#define LLONG_MIN_MSEC_UNDERFLOW(sec, msec) \
+ ((sec == LLONG_MIN/1000 && msec < LLONG_MIN%1000) \
+ || (sec < LLONG_MIN/1000))
+
+/*
+ * Normalize timespec so that abs(tv_nsec) is smaller than 1s.
+ */
+static inline struct timespec tst_normalize_timespec(struct timespec t)
+{
+ t.tv_sec += t.tv_nsec / 1000000000;
+ t.tv_nsec %= 1000000000;
+
+ return t;
+}
+
+/*
+ * Normalize timeval so that abs(tv_usec) is smaller than 1s.
+ */
+static inline struct timeval tst_normalize_timeval(struct timeval t)
+{
+ t.tv_sec += t.tv_usec / 1000000;
+ t.tv_usec %= 1000000;
+
+ return t;
+}
/*
- * Converts timespec to microseconds.
+ * Saturated conversion from timespec to microseconds.
*/
static inline long long tst_timespec_to_us(struct timespec t)
{
- return t.tv_sec * 1000000 + (t.tv_nsec + 500) / 1000;
+ t = tst_normalize_timespec(t);
+
+ long long usec = (t.tv_nsec + 500) / 1000;
+
+#if LONG_MAX > 0xffffffff
+ if (LLONG_MAX_USEC_OVERFLOW(t.tv_sec, usec))
+ return LLONG_MAX;
+
+ if (LLONG_MIN_USEC_UNDERFLOW(t.tv_sec, usec))
+ return LLONG_MIN;
+#endif
+
+ return t.tv_sec * 1000000 + usec;
}
/*
- * Converts timespec to miliseconds.
+ * Saturated conversion from timespec to miliseconds.
*/
static inline long long tst_timespec_to_ms(struct timespec t)
{
- return t.tv_sec * 1000 + (t.tv_nsec + 500000) / 1000000;
+ t = tst_normalize_timespec(t);
+
+ long long msec = (t.tv_nsec + 500000) / 1000000;
+
+#if LONG_MAX > 0xffffffff
+ if (LLONG_MAX_MSEC_OVERFLOW(t.tv_sec, msec))
+ return LLONG_MAX;
+
+ if (LLONG_MIN_MSEC_UNDERFLOW(t.tv_sec, msec))
+ return LLONG_MIN;
+#endif
+
+ return t.tv_sec * 1000 + msec;
}
/*
- * Converts timeval to microseconds.
+ * Saturated conversion from timeval to microseconds.
*/
static inline long long tst_timeval_to_us(struct timeval t)
{
- return t.tv_sec * 1000000 + t.tv_usec;
+ t = tst_normalize_timeval(t);
+
+ long long usec = t.tv_usec;
+
+#if LONG_MAX > 0xffffffff
+ if (LLONG_MAX_USEC_OVERFLOW(t.tv_sec, usec))
+ return LLONG_MAX;
+
+ if (LLONG_MIN_USEC_UNDERFLOW(t.tv_sec, usec))
+ return LLONG_MIN;
+#endif
+
+ return t.tv_sec * 1000000 + usec;
}
/*
- * Converts timeval to miliseconds.
+ * Saturated conversion from timeval to miliseconds.
*/
static inline long long tst_timeval_to_ms(struct timeval t)
{
- return t.tv_sec * 1000 + (t.tv_usec + 500) / 1000;
+ t = tst_normalize_timeval(t);
+
+ long long msec = (t.tv_usec + 500) / 1000;
+
+#if LONG_MAX > 0xffffffff
+ if (LLONG_MAX_MSEC_OVERFLOW(t.tv_sec, msec))
+ return LLONG_MAX;
+
+ if (LLONG_MIN_MSEC_UNDERFLOW(t.tv_sec, msec))
+ return LLONG_MIN;
+#endif
+
+ return t.tv_sec * 1000 + msec;
}
/*
@@ -93,6 +180,32 @@ static inline struct timeval tst_us_to_timeval(long long us)
}
/*
+ * Converts ms to struct timespec
+ */
+static inline struct timespec tst_ms_to_timespec(long long ms)
+{
+ struct timespec ret;
+
+ ret.tv_sec = ms / 1000;
+ ret.tv_nsec = (ms % 1000) * 1000000;
+
+ return ret;
+}
+
+/*
+ * Converts us to struct timespec
+ */
+static inline struct timespec tst_us_to_timespec(long long us)
+{
+ struct timespec ret;
+
+ ret.tv_sec = us / 1000000;
+ ret.tv_nsec = (us % 1000000) * 1000;
+
+ return ret;
+}
+
+/*
* Comparsions
*/
static inline int tst_timespec_lt(struct timespec t1, struct timespec t2)
diff --git a/lib/newlib_tests/.gitignore b/lib/newlib_tests/.gitignore
index 8e120074e..0405c3e2e 100644
--- a/lib/newlib_tests/.gitignore
+++ b/lib/newlib_tests/.gitignore
@@ -15,3 +15,4 @@ test14
tst_device
tst_safe_fileops
tst_res_hexd
+tst_timer
diff --git a/lib/newlib_tests/tst_timer.c b/lib/newlib_tests/tst_timer.c
new file mode 100644
index 000000000..d29ac263b
--- /dev/null
+++ b/lib/newlib_tests/tst_timer.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ /*
+ * Tests saturated timeval and timespec to us and ms conversions.
+ */
+
+#include "tst_test.h"
+#include "tst_timer.h"
+
+static void timeval_overflow_us_test(long long us_add)
+{
+ struct timeval tv;
+ long long us;
+
+ tst_res(TINFO, "Testing for timeval overflow by %llius", us_add);
+
+ tv = tst_us_to_timeval(LLONG_MAX);
+ tv.tv_usec += us_add;
+
+ tst_res(TINFO, "tv_sec=%li tv_usec=%li", tv.tv_sec, tv.tv_usec);
+
+ us = tst_timeval_to_us(tv);
+
+ long long expected = LLONG_MAX;
+
+ if (us_add < 0)
+ expected = LLONG_MAX + us_add;
+
+ if (us != expected)
+ tst_res(TFAIL, "Got %lli, expected %lli", us, expected);
+ else
+ tst_res(TPASS, "Got %lli", expected);
+}
+
+static void timeval_underflow_us_test(long long us_add)
+{
+ struct timeval tv;
+ long long us;
+
+ tst_res(TINFO, "Testing for timeval underflow by %llius", us_add);
+
+ tv = tst_us_to_timeval(LLONG_MIN);
+ tv.tv_usec += us_add;
+
+ tst_res(TINFO, "tv_sec=%li tv_usec=%li", tv.tv_sec, tv.tv_usec);
+
+ us = tst_timeval_to_us(tv);
+
+ long long expected = LLONG_MIN;
+
+ if (us_add > 0)
+ expected = LLONG_MIN + us_add;
+
+ if (us != expected)
+ tst_res(TFAIL, "Got %lli, expected %lli", us, expected);
+ else
+ tst_res(TPASS, "Got %lli", expected);
+}
+
+static void timespec_overflow_us_test(long long us_add)
+{
+ struct timespec ts;
+ long long us;
+
+ tst_res(TINFO, "Testing for timespec overflow by %llius", us_add);
+
+ ts = tst_us_to_timespec(LLONG_MAX);
+ ts.tv_nsec += us_add * 1000;
+
+ tst_res(TINFO, "tv_sec=%li tv_nsec=%li", ts.tv_sec, ts.tv_nsec);
+
+ us = tst_timespec_to_us(ts);
+
+ long long expected = LLONG_MAX;
+
+ if (us_add < 0)
+ expected = LLONG_MAX + us_add;
+
+ if (us != expected)
+ tst_res(TFAIL, "Got %lli, expected %lli", us, expected);
+ else
+ tst_res(TPASS, "Got %lli", expected);
+}
+
+static void do_test(void)
+{
+ if (sizeof(time_t) == 4)
+ tst_brk(TCONF, "sizeof(time_t) == 4");
+
+ timeval_overflow_us_test(0);
+ timeval_overflow_us_test(1);
+ timeval_overflow_us_test(-1);
+ timeval_overflow_us_test(1000000);
+ timeval_overflow_us_test(-1000000);
+
+ timeval_underflow_us_test(0);
+ timeval_underflow_us_test(1);
+ timeval_underflow_us_test(-1);
+ timeval_underflow_us_test(1000000);
+ timeval_underflow_us_test(-1000000);
+
+ timespec_overflow_us_test(0);
+ timespec_overflow_us_test(1);
+ timespec_overflow_us_test(-1);
+ timespec_overflow_us_test(100000);
+ timespec_overflow_us_test(-100000);
+}
+
+static struct tst_test test = {
+ .test_all = do_test,
+};
--
2.13.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [LTP] [RFC] [PATCH 2/2] tst_timer.h: Make time conversions saturated
2017-06-13 16:00 ` [LTP] [RFC] [PATCH 2/2] tst_timer.h: Make time conversions saturated Cyril Hrubis
@ 2017-06-14 14:47 ` Jan Stancek
2017-06-14 14:53 ` Cyril Hrubis
0 siblings, 1 reply; 6+ messages in thread
From: Jan Stancek @ 2017-06-14 14:47 UTC (permalink / raw)
To: ltp
----- Original Message -----
> The conversions of struct timeval and struct timespec to us and ms are
> now saturated so instead of overflowing/underflowing long long these
> return LLONG_MAX/LLONG_MIN.
>
> This commit also adds tst_us_to_timespec(), tst_ms_to_timespec() and
> newlib_tests/tst_timer test to assert that the saturated conversion
> actually works.
>
> Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> ---
There's one issue I'm running into, default language std is older
than c99. So with plain configure && make, I fail on:
../include/tst_timer.h:86: error: ‘LLONG_MAX’ undeclared (first use in this function)
../include/tst_timer.h:89: error: ‘LLONG_MIN’ undeclared (first use in this function)
With CFLAGS="-std=gnu99" I run into one minor issue:
clock_nanosleep01.c:64:17: error: initializer element is not constant
but after resolving that, all compiles.
---
What is reasoning behind these ifdefs?
#if LONG_MAX > 0xffffffff
Regards,
Jan
^ permalink raw reply [flat|nested] 6+ messages in thread
* [LTP] [RFC] [PATCH 2/2] tst_timer.h: Make time conversions saturated
2017-06-14 14:47 ` Jan Stancek
@ 2017-06-14 14:53 ` Cyril Hrubis
0 siblings, 0 replies; 6+ messages in thread
From: Cyril Hrubis @ 2017-06-14 14:53 UTC (permalink / raw)
To: ltp
Hi!
> > The conversions of struct timeval and struct timespec to us and ms are
> > now saturated so instead of overflowing/underflowing long long these
> > return LLONG_MAX/LLONG_MIN.
> >
> > This commit also adds tst_us_to_timespec(), tst_ms_to_timespec() and
> > newlib_tests/tst_timer test to assert that the saturated conversion
> > actually works.
> >
> > Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
> > ---
>
> There's one issue I'm running into, default language std is older
> than c99. So with plain configure && make, I fail on:
> ../include/tst_timer.h:86: error: ???LLONG_MAX??? undeclared (first use in this function)
> ../include/tst_timer.h:89: error: ???LLONG_MIN??? undeclared (first use in this function)
Supposedly we should set _GNU_SOURCE in all testcases that include that
header after the change. Or set up fallback LLONG_MAX and LLONG_MIN
definitions.
> What is reasoning behind these ifdefs?
> #if LONG_MAX > 0xffffffff
To shut up warnings. If we compile on 32bit platform these conditions
are always false and we got warnings, a lot of them for each source that
includes the header. And since time_t size is as far as I can tell the
same as long we check if LONG_MAX is 64bit or not that way. Checking for
time_t size with autoconf would be a bit cleaner solution though.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 6+ messages in thread
* [LTP] [RFC] [PATCH 2/2] tst_timer.h: Make time conversions saturated
@ 2017-08-01 15:42 Cyril Hrubis
2017-08-02 8:17 ` Cyril Hrubis
0 siblings, 1 reply; 6+ messages in thread
From: Cyril Hrubis @ 2017-08-01 15:42 UTC (permalink / raw)
To: ltp
The conversions of struct timeval and struct timespec to us and ms are
now saturated so instead of overflowing/underflowing long long these
return LLONG_MAX/LLONG_MIN.
This commit also adds tst_us_to_timespec(), tst_ms_to_timespec() and
newlib_tests/tst_timer test to assert that the saturated conversion
actually works.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
include/tst_timer.h | 129 ++++++++++++++++++++++++++++++++++++++++---
lib/newlib_tests/.gitignore | 1 +
lib/newlib_tests/tst_timer.c | 126 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 248 insertions(+), 8 deletions(-)
create mode 100644 lib/newlib_tests/tst_timer.c
diff --git a/include/tst_timer.h b/include/tst_timer.h
index f294b0eb7..b1f595bd4 100644
--- a/include/tst_timer.h
+++ b/include/tst_timer.h
@@ -33,37 +33,124 @@
#include <sys/time.h>
#include <time.h>
+#include <limits.h>
+
+#define LLONG_MAX_USEC_OVERFLOW(sec, usec) \
+ (sizeof(time_t) == 8 && ((sec == LLONG_MAX/1000000 && usec > LLONG_MAX%1000000) \
+ || (sec > LLONG_MAX/1000000)))
+
+#define LLONG_MIN_USEC_UNDERFLOW(sec, usec) \
+ ((sec == LLONG_MIN/1000000 && usec < LLONG_MIN%1000000) \
+ || (sec < LLONG_MIN/1000000))
+
+#define LLONG_MAX_MSEC_OVERFLOW(sec, msec) \
+ ((sec == LLONG_MAX/1000 && msec > LLONG_MAX%1000) \
+ || (sec > LLONG_MAX/1000))
+
+#define LLONG_MIN_MSEC_UNDERFLOW(sec, msec) \
+ ((sec == LLONG_MIN/1000 && msec < LLONG_MIN%1000) \
+ || (sec < LLONG_MIN/1000))
+
+/*
+ * Normalize timespec so that abs(tv_nsec) is smaller than 1s.
+ */
+static inline struct timespec tst_normalize_timespec(struct timespec t)
+{
+ t.tv_sec += t.tv_nsec / 1000000000;
+ t.tv_nsec %= 1000000000;
+
+ return t;
+}
+
+/*
+ * Normalize timeval so that abs(tv_usec) is smaller than 1s.
+ */
+static inline struct timeval tst_normalize_timeval(struct timeval t)
+{
+ t.tv_sec += t.tv_usec / 1000000;
+ t.tv_usec %= 1000000;
+
+ return t;
+}
/*
- * Converts timespec to microseconds.
+ * Saturated conversion from timespec to microseconds.
*/
static inline long long tst_timespec_to_us(struct timespec t)
{
- return t.tv_sec * 1000000 + (t.tv_nsec + 500) / 1000;
+ t = tst_normalize_timespec(t);
+
+ long long usec = (t.tv_nsec + 500) / 1000;
+
+#if LONG_MAX > 0xffffffff
+ if (LLONG_MAX_USEC_OVERFLOW(t.tv_sec, usec))
+ return LLONG_MAX;
+
+ if (LLONG_MIN_USEC_UNDERFLOW(t.tv_sec, usec))
+ return LLONG_MIN;
+#endif
+
+ return t.tv_sec * 1000000 + usec;
}
/*
- * Converts timespec to miliseconds.
+ * Saturated conversion from timespec to miliseconds.
*/
static inline long long tst_timespec_to_ms(struct timespec t)
{
- return t.tv_sec * 1000 + (t.tv_nsec + 500000) / 1000000;
+ t = tst_normalize_timespec(t);
+
+ long long msec = (t.tv_nsec + 500000) / 1000000;
+
+#if LONG_MAX > 0xffffffff
+ if (LLONG_MAX_MSEC_OVERFLOW(t.tv_sec, msec))
+ return LLONG_MAX;
+
+ if (LLONG_MIN_MSEC_UNDERFLOW(t.tv_sec, msec))
+ return LLONG_MIN;
+#endif
+
+ return t.tv_sec * 1000 + msec;
}
/*
- * Converts timeval to microseconds.
+ * Saturated conversion from timeval to microseconds.
*/
static inline long long tst_timeval_to_us(struct timeval t)
{
- return t.tv_sec * 1000000 + t.tv_usec;
+ t = tst_normalize_timeval(t);
+
+ long long usec = t.tv_usec;
+
+#if LONG_MAX > 0xffffffff
+ if (LLONG_MAX_USEC_OVERFLOW(t.tv_sec, usec))
+ return LLONG_MAX;
+
+ if (LLONG_MIN_USEC_UNDERFLOW(t.tv_sec, usec))
+ return LLONG_MIN;
+#endif
+
+ return t.tv_sec * 1000000 + usec;
}
/*
- * Converts timeval to miliseconds.
+ * Saturated conversion from timeval to miliseconds.
*/
static inline long long tst_timeval_to_ms(struct timeval t)
{
- return t.tv_sec * 1000 + (t.tv_usec + 500) / 1000;
+ t = tst_normalize_timeval(t);
+
+ long long msec = (t.tv_usec + 500) / 1000;
+
+#if LONG_MAX > 0xffffffff
+ if (LLONG_MAX_MSEC_OVERFLOW(t.tv_sec, msec))
+ return LLONG_MAX;
+
+ if (LLONG_MIN_MSEC_UNDERFLOW(t.tv_sec, msec))
+ return LLONG_MIN;
+#endif
+
+ return t.tv_sec * 1000 + msec;
}
/*
@@ -93,6 +180,32 @@ static inline struct timeval tst_us_to_timeval(long long us)
}
/*
+ * Converts ms to struct timespec
+ */
+static inline struct timespec tst_ms_to_timespec(long long ms)
+{
+ struct timespec ret;
+
+ ret.tv_sec = ms / 1000;
+ ret.tv_nsec = (ms % 1000) * 1000000;
+
+ return ret;
+}
+
+/*
+ * Converts us to struct timespec
+ */
+static inline struct timespec tst_us_to_timespec(long long us)
+{
+ struct timespec ret;
+
+ ret.tv_sec = us / 1000000;
+ ret.tv_nsec = (us % 1000000) * 1000;
+
+ return ret;
+}
+
+/*
* Comparsions
*/
static inline int tst_timespec_lt(struct timespec t1, struct timespec t2)
diff --git a/lib/newlib_tests/.gitignore b/lib/newlib_tests/.gitignore
index 8e120074e..0405c3e2e 100644
--- a/lib/newlib_tests/.gitignore
+++ b/lib/newlib_tests/.gitignore
@@ -15,3 +15,4 @@ test14
tst_device
tst_safe_fileops
tst_res_hexd
+tst_timer
diff --git a/lib/newlib_tests/tst_timer.c b/lib/newlib_tests/tst_timer.c
new file mode 100644
index 000000000..d29ac263b
--- /dev/null
+++ b/lib/newlib_tests/tst_timer.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ /*
+ * Tests saturated timeval and timespec to us and ms conversions.
+ */
+
+#include "tst_test.h"
+#include "tst_timer.h"
+
+static void timeval_overflow_us_test(long long us_add)
+{
+ struct timeval tv;
+ long long us;
+
+ tst_res(TINFO, "Testing for timeval overflow by %llius", us_add);
+
+ tv = tst_us_to_timeval(LLONG_MAX);
+ tv.tv_usec += us_add;
+
+ tst_res(TINFO, "tv_sec=%li tv_usec=%li", tv.tv_sec, tv.tv_usec);
+
+ us = tst_timeval_to_us(tv);
+
+ long long expected = LLONG_MAX;
+
+ if (us_add < 0)
+ expected = LLONG_MAX + us_add;
+
+ if (us != expected)
+ tst_res(TFAIL, "Got %lli, expected %lli", us, expected);
+ else
+ tst_res(TPASS, "Got %lli", expected);
+}
+
+static void timeval_underflow_us_test(long long us_add)
+{
+ struct timeval tv;
+ long long us;
+
+ tst_res(TINFO, "Testing for timeval underflow by %llius", us_add);
+
+ tv = tst_us_to_timeval(LLONG_MIN);
+ tv.tv_usec += us_add;
+
+ tst_res(TINFO, "tv_sec=%li tv_usec=%li", tv.tv_sec, tv.tv_usec);
+
+ us = tst_timeval_to_us(tv);
+
+ long long expected = LLONG_MIN;
+
+ if (us_add > 0)
+ expected = LLONG_MIN + us_add;
+
+ if (us != expected)
+ tst_res(TFAIL, "Got %lli, expected %lli", us, expected);
+ else
+ tst_res(TPASS, "Got %lli", expected);
+}
+
+static void timespec_overflow_us_test(long long us_add)
+{
+ struct timespec ts;
+ long long us;
+
+ tst_res(TINFO, "Testing for timespec overflow by %llius", us_add);
+
+ ts = tst_us_to_timespec(LLONG_MAX);
+ ts.tv_nsec += us_add * 1000;
+
+ tst_res(TINFO, "tv_sec=%li tv_nsec=%li", ts.tv_sec, ts.tv_nsec);
+
+ us = tst_timespec_to_us(ts);
+
+ long long expected = LLONG_MAX;
+
+ if (us_add < 0)
+ expected = LLONG_MAX + us_add;
+
+ if (us != expected)
+ tst_res(TFAIL, "Got %lli, expected %lli", us, expected);
+ else
+ tst_res(TPASS, "Got %lli", expected);
+}
+
+static void do_test(void)
+{
+ if (sizeof(time_t) == 4)
+ tst_brk(TCONF, "sizeof(time_t) == 4");
+
+ timeval_overflow_us_test(0);
+ timeval_overflow_us_test(1);
+ timeval_overflow_us_test(-1);
+ timeval_overflow_us_test(1000000);
+ timeval_overflow_us_test(-1000000);
+
+ timeval_underflow_us_test(0);
+ timeval_underflow_us_test(1);
+ timeval_underflow_us_test(-1);
+ timeval_underflow_us_test(1000000);
+ timeval_underflow_us_test(-1000000);
+
+ timespec_overflow_us_test(0);
+ timespec_overflow_us_test(1);
+ timespec_overflow_us_test(-1);
+ timespec_overflow_us_test(100000);
+ timespec_overflow_us_test(-100000);
+}
+
+static struct tst_test test = {
+ .test_all = do_test,
+};
--
2.13.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [LTP] [RFC] [PATCH 2/2] tst_timer.h: Make time conversions saturated
2017-08-01 15:42 Cyril Hrubis
@ 2017-08-02 8:17 ` Cyril Hrubis
0 siblings, 0 replies; 6+ messages in thread
From: Cyril Hrubis @ 2017-08-02 8:17 UTC (permalink / raw)
To: ltp
Hi!
> The conversions of struct timeval and struct timespec to us and ms are
> now saturated so instead of overflowing/underflowing long long these
> return LLONG_MAX/LLONG_MIN.
>
> This commit also adds tst_us_to_timespec(), tst_ms_to_timespec() and
> newlib_tests/tst_timer test to assert that the saturated conversion
> actually works.
Argh, I've send a wrong patch, sorry.
But I wanted to ping this one anyway.
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-08-02 8:17 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-13 16:00 [LTP] [COMMITTED] [PATCH 1/2] tst_timer.h: Add timeval helpers Cyril Hrubis
2017-06-13 16:00 ` [LTP] [RFC] [PATCH 2/2] tst_timer.h: Make time conversions saturated Cyril Hrubis
2017-06-14 14:47 ` Jan Stancek
2017-06-14 14:53 ` Cyril Hrubis
-- strict thread matches above, loose matches on Subject: below --
2017-08-01 15:42 Cyril Hrubis
2017-08-02 8:17 ` Cyril Hrubis
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.