Commit 74c9c0e7 authored by Christopher Friedt's avatar Christopher Friedt Committed by Fabio Baltieri
Browse files

tests: time_units: check for overflow in z_tmcvt intermediate



Prior to #41602, due to the ordering of operations (first mul,
then div), an intermediate value would overflow, resulting in
a time non-linearity.

This test ensures that time rolls-over properly.

Signed-off-by: default avatarChris Friedt <cfriedt@meta.com>
parent 50473ec0
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
# Copyright 2022 Meta
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr COMPONENTS unittest REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(time_units)

FILE(GLOB app_sources *.c)
target_sources(testbinary PRIVATE ${app_sources})
+9 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 Meta
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/ztest.h>

ZTEST_SUITE(time_units, NULL, NULL, NULL, NULL, NULL);
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright 2022 Meta
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>

#include <zephyr/sys/time_units.h>
#include <zephyr/ztest.h>

/**
 * @brief Test @ref z_tmcvt for robustness against intermediate value overflow.
 *
 * With input
 * ```
 * [t0, t1, t2] = [
 *   UINT64_MAX / to_hz - 1,
 *   UINT64_MAX / to_hz,
 *   UINT64_MAX / to_hz + 1,
 * ]
 * ```
 *
 * passed through @ref z_tmcvt, we expect a linear sequence:
 * ```
 * [
 *   562949953369140,
 *   562949953399658,
 *   562949953430175,
 * ]
 * ```
 *
 * If an overflow occurs, we see something like the following:
 * ```
 * [
 *   562949953369140,
 *   562949953399658,
 *   8863,
 * ]
 * ```
 */
ZTEST(time_units, test_z_tmcvt_for_overflow)
{
	const uint32_t from_hz = 32768UL;
	const uint32_t to_hz = 1000000000UL;

	zassert_equal(562949953369140ULL,
		      z_tmcvt(UINT64_MAX / to_hz - 1, from_hz, to_hz, true, false, false, false));
	zassert_equal(562949953399658ULL,
		      z_tmcvt(UINT64_MAX / to_hz, from_hz, to_hz, true, false, false, false));
	zassert_equal(562949953430175ULL,
		      z_tmcvt(UINT64_MAX / to_hz + 1, from_hz, to_hz, true, false, false, false));
}
+2 −0
Original line number Diff line number Diff line
CONFIG_ZTEST=y
CONFIG_ZTEST_NEW_API=y
+5 −0
Original line number Diff line number Diff line
common:
  tags: time_units
  type: unit
tests:
  utilities.time_units.z_tmcvt: {}