Index: sys/sys/time.h =================================================================== --- sys/sys/time.h +++ sys/sys/time.h @@ -220,7 +220,11 @@ sbttous(sbintime_t _sbt) { - return ((1000000 * _sbt) >> 32); +#ifdef KASSERT + KASSERT(_sbt >= 0, ("Negative values illegal for sbttous: %jx", _sbt)); +#endif + return ((_sbt >> 32) * 1000000 + + (1000000 * (_sbt & 0xffffffffu) >> 32)); } static __inline sbintime_t @@ -243,8 +247,10 @@ static __inline int64_t sbttoms(sbintime_t _sbt) { - - return ((1000 * _sbt) >> 32); +#ifdef KASSERT + KASSERT(_sbt >= 0, ("Negative values illegal for sbttoms: %jx", _sbt)); +#endif + return ((_sbt >> 32) * 1000 + (1000 * (_sbt & 0xffffffffu) >> 32)); } static __inline sbintime_t Index: tests/sys/sys/Makefile =================================================================== --- tests/sys/sys/Makefile +++ tests/sys/sys/Makefile @@ -9,7 +9,8 @@ bitstring_test \ qmath_test \ rb_test \ - splay_test + splay_test \ + time_test .if ${COMPILER_TYPE} == "gcc" CFLAGS.bitstring_test= -fno-strict-overflow Index: tests/sys/sys/time_test.c =================================================================== --- /dev/null +++ tests/sys/sys/time_test.c @@ -0,0 +1,202 @@ +/*- + * Copyright (c) 2022 Axcient + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ +#include +#include + +#include + +#include + + +static void +atf_check_nstosbt(sbintime_t expected, int64_t ns) { + sbintime_t actual = nstosbt(ns); + + ATF_CHECK_MSG((expected) - 1 <= (actual) && actual <= (expected) + 1, + "%ld != nstosbt(%ld) (%ld)", + expected, ns, actual); +} + +ATF_TC_WITHOUT_HEAD(nstosbt); +ATF_TC_BODY(nstosbt, tc) +{ + atf_check_nstosbt(0, 0); + atf_check_nstosbt(4, 1); + /* 1 second */ + atf_check_nstosbt((1ll << 32) - 4, 999999999); + atf_check_nstosbt(1ll << 32, 1000000000); + /* 2 seconds https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263073 */ + atf_check_nstosbt((1ll << 33) - 4, 1999999999); + atf_check_nstosbt(1ll << 33, 2000000000); + /* Max value */ + atf_check_nstosbt(((1ll << 31) - 1) << 32, + ((1ll << 31) - 1) * 1000000000); +} + +static void +atf_check_ustosbt(sbintime_t expected, int64_t us) { + sbintime_t actual = ustosbt(us); + + ATF_CHECK_MSG((expected) - 1 <= (actual) && actual <= (expected) + 1, + "%ld != ustosbt(%ld) (%ld)", + expected, us, actual); +} + +ATF_TC_WITHOUT_HEAD(ustosbt); +ATF_TC_BODY(ustosbt, tc) +{ + atf_check_ustosbt(0, 0); + atf_check_ustosbt(4295, 1); + /* 1 second */ + atf_check_ustosbt(4294963002, 999999); + atf_check_ustosbt(1ll << 32, 1000000); + /* 2 seconds https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263073 */ + atf_check_ustosbt(8589930297, 1999999); + atf_check_ustosbt(1ll << 33, 2000000); + /* Max value */ + atf_check_ustosbt(((1ull << 31) - 1) << 32, + ((1ll << 31) - 1) * 1000000); +} + +static void +atf_check_mstosbt(sbintime_t expected, int64_t ms) { + sbintime_t actual = mstosbt(ms); + + ATF_CHECK_MSG((expected) - 1 <= (actual) && actual <= (expected) + 1, + "%ld != mstosbt(%ld) (%ld)", + expected, ms, actual); +} + +ATF_TC_WITHOUT_HEAD(mstosbt); +ATF_TC_BODY(mstosbt, tc) +{ + atf_check_mstosbt(0, 0); + atf_check_mstosbt(4294967, 1); + /* 1 second */ + atf_check_mstosbt(4290672328, 999); + atf_check_mstosbt(1ll << 32, 1000); + /* 2 seconds https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=263073 */ + atf_check_mstosbt(8585639624, 1999); + atf_check_mstosbt(1ll << 33, 2000); + /* Max value */ + atf_check_mstosbt(((1ll << 31) - 1) << 32, ((1ll << 31) - 1) * 1000); +} + +static void +atf_check_sbttons(int64_t expected, sbintime_t sbt) { + int64_t actual = sbttons(sbt); + + ATF_CHECK_MSG((expected) - 1 <= (actual) && actual <= (expected) + 1, + "%ld != sbttons(%ld) (%ld)", + expected, sbt, actual); +} + +ATF_TC_WITHOUT_HEAD(sbttons); +ATF_TC_BODY(sbttons, tc) +{ + atf_check_sbttons(0, 0); + atf_check_sbttons(0, 1); + atf_check_sbttons(1, (1ll << 32) / 1000000000); + /* 1 second */ + atf_check_sbttons(1000000000, 1ll << 32); + atf_check_sbttons(1999999999, (1ll << 33) - 1); + /* 2 seconds */ + atf_check_sbttons(2000000000, 1ll << 33); + /* edge cases */ + atf_check_sbttons(999999999, (1ll << 32) - 1); + atf_check_sbttons(2147483648000000000, (1ull << 63) - 1); +} + +static void +atf_check_sbttous(int64_t expected, sbintime_t sbt) { + int64_t actual = sbttous(sbt); + + ATF_CHECK_MSG((expected) - 1 <= (actual) && actual <= (expected) + 1, + "%ld != sbttous(%ld) (%ld)", + expected, sbt, actual); +} + +ATF_TC_WITHOUT_HEAD(sbttous); +ATF_TC_BODY(sbttous, tc) +{ + atf_check_sbttous(0, 0); + atf_check_sbttous(0, 1); + atf_check_sbttous(1, (1ll << 32) / 1000000); + /* 1 second */ + atf_check_sbttous(1000000, 1ll << 32); + atf_check_sbttous(1999999, (1ll << 33) - 1); + /* 2 seconds */ + atf_check_sbttous(2000000, 1ll << 33); + /* Overflows (bug 263073) */ + atf_check_sbttous(1ll << 31, 9223372036854); + atf_check_sbttous(1ll << 31, 9223372036855); + atf_check_sbttous(2147483648000000, (1ull << 63) - 1); +} + +static void +atf_check_sbttoms(int64_t expected, sbintime_t sbt) { + int64_t actual = sbttoms(sbt); + + ATF_CHECK_MSG((expected) - 1 <= (actual) && actual <= (expected) + 1, + "%ld != sbttoms(%ld) (%ld)", + expected, sbt, actual); +} + +ATF_TC_WITHOUT_HEAD(sbttoms); +ATF_TC_BODY(sbttoms, tc) +{ + atf_check_sbttoms(0, 0); + atf_check_sbttoms(0, 1); + atf_check_sbttoms(1, (1ll << 32) / 1000); + /* 1 second */ + atf_check_sbttoms(1000, 1ll << 32); + atf_check_sbttoms(1999, (1ll << 33) - 1); + /* 2 seconds */ + atf_check_sbttoms(2000, 1ll << 33); + /* Overflows (bug 263073) */ + atf_check_sbttoms(1ll << 31, 9223372036854775); + atf_check_sbttoms(1ll << 31, 9223372036854776); + atf_check_sbttoms(2147483648000, (1ull << 63) - 1); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, nstosbt); + ATF_TP_ADD_TC(tp, ustosbt); + ATF_TP_ADD_TC(tp, mstosbt); + ATF_TP_ADD_TC(tp, sbttons); + ATF_TP_ADD_TC(tp, sbttous); + ATF_TP_ADD_TC(tp, sbttoms); + + return (atf_no_error()); +}