blob: ed04718ca58584daa8f04fe9e1a7698d41279e4f [file] [log] [blame]
/* timestamp.h - macroses for measuring time in benchmarking tests */
/*
* Copyright (c) 2012-2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* DESCRIPTION
* This file contains the macroses for taking and converting time for
* benchmarking tests.
*/
#ifndef _TIMESTAMP_H_
#define _TIMESTAMP_H_
#include <zephyr.h>
#include <limits.h>
#if defined(__GNUC__)
#include <test_asm_inline_gcc.h>
#else
#include <test_asm_inline_other.h>
#endif
typedef int64_t TICK_TYPE;
#define TICK_SYNCH() task_sleep(1)
#define TICK_GET(x) ((TICK_TYPE) sys_tick_delta(x))
#define OS_GET_TIME() sys_cycle_get_32()
/* time necessary to read the time */
extern uint32_t tm_off;
static inline uint32_t TIME_STAMP_DELTA_GET(uint32_t ts)
{
uint32_t t;
/* serialize so OS_GET_TIME() is not reordered */
timestamp_serialize();
t = OS_GET_TIME();
uint32_t res = (t >= ts) ? (t - ts) : (ULONG_MAX - ts + t);
if (ts > 0) {
res -= tm_off;
}
return res;
}
/*
* Routine initializes the benchmark timing measurement
* The function sets up the global variable tm_off
*/
static inline void bench_test_init(void)
{
uint32_t t = OS_GET_TIME();
tm_off = OS_GET_TIME() - t;
}
/* number of ticks before timer overflows */
#define BENCH_MAX_TICKS (sys_clock_ticks_per_sec - 1)
/* tickstamp used for timer counter overflow check */
static TICK_TYPE tCheck;
/*
* Routines are invoked before and after the benchmark and check
* if penchmarking code took less time than necessary for the
* high precision timer register overflow.
* Functions modify the tCheck global variable.
*/
static inline void bench_test_start(void)
{
tCheck = 0;
/* before reading time we synchronize to the start of the timer tick */
TICK_SYNCH();
tCheck = TICK_GET(&tCheck);
}
/* returns 0 if the number of ticks is valid and -1 if not */
static inline int bench_test_end(void)
{
tCheck = TICK_GET(&tCheck);
if (tCheck > BENCH_MAX_TICKS) {
return -1;
}
return 0;
}
/*
* Returns -1 if number of ticks cause high precision timer counter
* overflow and 0 otherwise
* Called after bench_test_end to see if we still can use timing
* results or is it completely invalid
*/
static inline int high_timer_overflow(void)
{
if (tCheck >= (UINT_MAX / sys_clock_hw_cycles_per_tick)) {
return -1;
}
return 0;
}
#endif /* _TIMESTAMP_H_ */