<commit_before>/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdlib.h>
#include <ztest.h>
#include <zephyr/types.h>

struct timer_data {
	int expire_cnt;
	int stop_cnt;
	int64_t timestamp;
};

#define DURATION 100
#define PERIOD 50
#define EXPIRE_TIMES 4
#define WITHIN_ERROR(var, target, epsilon) (abs((target) - (var)) <= (epsilon))

/* ms can be converted precisely to ticks only when a ms is exactly
 * represented by an integral number of ticks.  If the conversion is
 * not precise, then the reverse conversion of a difference in ms can
 * end up being off by a tick depending on the relative error between
 * the first and second ms conversion, and we need to adjust the
 * tolerance interval.
 */
#define INEXACT_MS_CONVERT ((CONFIG_SYS_CLOCK_TICKS_PER_SEC % MSEC_PER_SEC) != 0)

#if CONFIG_NRF_RTC_TIMER
/* On Nordic SOCs one or both of the tick and busy-wait clocks may
 * derive from sources that have slews that sum to +/- 13%.
 */
#define BUSY_TICK_SLEW_PPM 130000U
#else
/* On other platforms assume the clocks are perfectly aligned. */
#define BUSY_TICK_SLEW_PPM 0U
#endif
#define PPM_DIVISOR 1000000U

/* If the tick clock is faster or slower than the busywait clock the
 * remaining time for a partially elapsed timer in ticks will be
 * larger or smaller than expected by a value that depends on the slew
 * between the two clocks.  Produce a maximum error for a given
 * duration in microseconds.
 */
#define BUSY_SLEW_THRESHOLD_TICKS(_us)				\
	k_us_to_ticks_ceil32((_us) * BUSY_TICK_SLEW_PPM		\
			     / PPM_DIVISOR)

static void duration_expire(struct k_timer *timer);
static void duration_stop(struct k_timer *timer);

/** TESTPOINT: init timer via K_TIMER_DEFINE */
K_TIMER_DEFINE(ktimer, duration_expire, duration_stop);

static struct k_timer duration_timer;
static struct k_timer period0_timer;
static struct k_timer expire_timer;
static struct k_timer sync_timer;
static struct k_timer periodicity_timer;
static struct k_timer status_timer;
static struct k_timer status_anytime_timer;
static struct k_timer status_sync_timer;
static struct k_timer remain_timer;

static ZTEST_BMEM struct timer_data tdata;

extern void test_time_conversions(void);

#define TIMER_ASSERT(exp, tmr)			 \
	do {					 \
		if (!(exp)) {			 \
			k_timer_stop(tmr);	 \
			zassert_true(exp, NULL); \
		}				 \
	} while (0)

static void init_timer_data(void)
{
	tdata.expire_cnt = 0;
	tdata.stop_cnt = 0;

	if (IS_ENABLED(CONFIG_MULTITHREADING)) {
		k_usleep(1); /* align to tick */
	}

	tdata.timestamp = k_uptime_get();
}

static bool interval_check(int64_t interval, int64_t desired)
{
	int64_t slop = INEXACT_MS_CONVERT ? 1 : 0;

	/* Tickless kernels will advance time inside of an ISR, so it
	 * is always possible (especially with high tick rates and
	 * slow CPUs) for us to arrive at the uptime check above too
	 * late to see a full period elapse before the next period.
	 * We can alias at both sides of the interval, so two
	 * one-ticks deltas (NOT one two-tick delta!)
	 */
	if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
		slop += 2 * k_ticks_to_ms_ceil32(1);
	}

	if (abs(interval - desired) > slop) {
		return false;
	}

	return true;
}

/* entry routines */
static void duration_expire(struct k_timer *timer)
{
	/** TESTPOINT: expire function */
	int64_t interval = k_uptime_delta(&tdata.timestamp);

	tdata.expire_cnt++;
	if (tdata.expire_cnt == 1) {
		TIMER_ASSERT(interval_check(interval, DURATION), timer);
	} else {
		TIMER_ASSERT(interval_check(interval, PERIOD), timer);
	}

	if (tdata.expire_cnt >= EXPIRE_TIMES) {
		k_timer_stop(timer);
	}
}<commit_msg>tests/timer_api: Use correct 'abs' macro with correct type parameter<commit_after>/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdlib.h>
#include <ztest.h>
#include <zephyr/types.h>

struct timer_data {
	int expire_cnt;
	int stop_cnt;
	int64_t timestamp;
};

#define DURATION 100
#define PERIOD 50
#define EXPIRE_TIMES 4
#define WITHIN_ERROR(var, target, epsilon) (llabs((int64_t) ((target) - (var))) <= (epsilon))

/* ms can be converted precisely to ticks only when a ms is exactly
 * represented by an integral number of ticks.  If the conversion is
 * not precise, then the reverse conversion of a difference in ms can
 * end up being off by a tick depending on the relative error between
 * the first and second ms conversion, and we need to adjust the
 * tolerance interval.
 */
#define INEXACT_MS_CONVERT ((CONFIG_SYS_CLOCK_TICKS_PER_SEC % MSEC_PER_SEC) != 0)

#if CONFIG_NRF_RTC_TIMER
/* On Nordic SOCs one or both of the tick and busy-wait clocks may
 * derive from sources that have slews that sum to +/- 13%.
 */
#define BUSY_TICK_SLEW_PPM 130000U
#else
/* On other platforms assume the clocks are perfectly aligned. */
#define BUSY_TICK_SLEW_PPM 0U
#endif
#define PPM_DIVISOR 1000000U

/* If the tick clock is faster or slower than the busywait clock the
 * remaining time for a partially elapsed timer in ticks will be
 * larger or smaller than expected by a value that depends on the slew
 * between the two clocks.  Produce a maximum error for a given
 * duration in microseconds.
 */
#define BUSY_SLEW_THRESHOLD_TICKS(_us)				\
	k_us_to_ticks_ceil32((_us) * BUSY_TICK_SLEW_PPM		\
			     / PPM_DIVISOR)

static void duration_expire(struct k_timer *timer);
static void duration_stop(struct k_timer *timer);

/** TESTPOINT: init timer via K_TIMER_DEFINE */
K_TIMER_DEFINE(ktimer, duration_expire, duration_stop);

static struct k_timer duration_timer;
static struct k_timer period0_timer;
static struct k_timer expire_timer;
static struct k_timer sync_timer;
static struct k_timer periodicity_timer;
static struct k_timer status_timer;
static struct k_timer status_anytime_timer;
static struct k_timer status_sync_timer;
static struct k_timer remain_timer;

static ZTEST_BMEM struct timer_data tdata;

extern void test_time_conversions(void);

#define TIMER_ASSERT(exp, tmr)			 \
	do {					 \
		if (!(exp)) {			 \
			k_timer_stop(tmr);	 \
			zassert_true(exp, NULL); \
		}				 \
	} while (0)

static void init_timer_data(void)
{
	tdata.expire_cnt = 0;
	tdata.stop_cnt = 0;

	if (IS_ENABLED(CONFIG_MULTITHREADING)) {
		k_usleep(1); /* align to tick */
	}

	tdata.timestamp = k_uptime_get();
}

static bool interval_check(int64_t interval, int64_t desired)
{
	int64_t slop = INEXACT_MS_CONVERT ? 1 : 0;

	/* Tickless kernels will advance time inside of an ISR, so it
	 * is always possible (especially with high tick rates and
	 * slow CPUs) for us to arrive at the uptime check above too
	 * late to see a full period elapse before the next period.
	 * We can alias at both sides of the interval, so two
	 * one-ticks deltas (NOT one two-tick delta!)
	 */
	if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
		slop += 2 * k_ticks_to_ms_ceil32(1);
	}

	if (!WITHIN_ERROR(interval, desired, slop)) {
		return false;
	}

	return true;
}

/* entry routines */
static void duration_expire(struct k_timer *timer)
{
	/** TESTPOINT: expire function */
	int64_t interval = k_uptime_delta(&tdata.timestamp);

	tdata.expire_cnt++;
	if (tdata.expire_cnt == 1) {
		TIMER_ASSERT(interval_check(interval, DURATION), timer);
	} else {
		TIMER_ASSERT(interval_check(interval, PERIOD), timer);
	}

	if (tdata.expire_cnt >= EXPIRE_TIMES) {
		k_timer_stop(timer);
	}
}
{'fraction_non_alphanumeric': 0.08763799918222707, 'fraction_numerical': 0.014719912770887284, 'mean_word_length': 4.348396501457726, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3939980', 'n_tokens_mistral': 2716, 'n_tokens_neox': 2503, 'n_words': 823}