diff --git a/tests/posix/common/src/clock.c b/tests/posix/common/src/clock.c index 0911e437acf..5e36ec11836 100644 --- a/tests/posix/common/src/clock.c +++ b/tests/posix/common/src/clock.c @@ -122,3 +122,67 @@ ZTEST(posix_apis, test_posix_realtime) zassert_true(rts.tv_nsec >= tv.tv_usec * NSEC_PER_USEC, "gettimeofday didn't provide correct result"); } + +static inline bool ts_gt(const struct timespec *a, const struct timespec *b) +{ + __ASSERT_NO_MSG(a->tv_nsec < NSEC_PER_SEC); + __ASSERT_NO_MSG(a->tv_nsec >= 0); + __ASSERT_NO_MSG(b->tv_nsec < NSEC_PER_SEC); + __ASSERT_NO_MSG(b->tv_nsec >= 0); + + if (a->tv_sec > b->tv_sec) { + return true; + } + + if (a->tv_sec < b->tv_sec) { + return false; + } + + if (a->tv_nsec > b->tv_nsec) { + return true; + } + + return false; +} + +static inline void ts_print(const char *label, const struct timespec *ts) +{ + printk("%s: {%" PRIu64 ", %" PRIu64 "}\n", label, (uint64_t)ts->tv_sec, + (uint64_t)ts->tv_nsec); +} + +ZTEST(posix_apis, test_clock_gettime_rollover) +{ + uint64_t t; + struct timespec ts[3]; + const uint64_t rollover_s = UINT64_MAX / CONFIG_SYS_CLOCK_TICKS_PER_SEC; + + printk("CONFIG_SYS_CLOCK_TICKS_PER_SEC: %u\n", CONFIG_SYS_CLOCK_TICKS_PER_SEC); + printk("rollover_s: %" PRIu64 "\n", rollover_s); + + t = UINT64_MAX - 1; + /* align to tick boundary */ + k_sleep(K_TICKS(1)); + sys_clock_tick_set(t); + zassert_ok(clock_gettime(CLOCK_MONOTONIC, &ts[0])); + ts_print("t-1", &ts[0]); + zassert_equal(rollover_s, ts[0].tv_sec); + + t = UINT64_MAX; + /* align to tick boundary */ + k_sleep(K_TICKS(1)); + sys_clock_tick_set(t); + zassert_ok(clock_gettime(CLOCK_MONOTONIC, &ts[1])); + ts_print("t+0", &ts[1]); + zassert_equal(rollover_s, ts[1].tv_sec); + zassert_true(ts_gt(&ts[1], &ts[0])); + + t = UINT64_MAX + 1; + /* align to tick boundary */ + k_sleep(K_TICKS(1)); + sys_clock_tick_set(t); + zassert_ok(clock_gettime(CLOCK_MONOTONIC, &ts[2])); + ts_print("t+1", &ts[2]); + zassert_equal(0, ts[2].tv_sec); + zassert_true(ts_gt(&ts[1], &ts[2])); +}