timing: do not repeatedly do init()/start()/stop()

We should not be initializing/starting/stoping timing functions
multiple times. So this changes how the timing functions are
structured to allow only one initialization, only start when
stopped, and only stop when started.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2020-10-14 11:15:40 -07:00 committed by Anas Nashif
commit 9be37553ee
13 changed files with 353 additions and 88 deletions

View file

@ -121,48 +121,48 @@ static inline uint64_t z_arm_dwt_freq_get(void)
#endif /* CONFIG_SOC_FAMILY_NRF */ #endif /* CONFIG_SOC_FAMILY_NRF */
} }
void timing_init(void) void arch_timing_init(void)
{ {
z_arm_dwt_init(NULL); z_arm_dwt_init(NULL);
} }
void timing_start(void) void arch_timing_start(void)
{ {
z_arm_dwt_cycle_count_start(); z_arm_dwt_cycle_count_start();
} }
void timing_stop(void) void arch_timing_stop(void)
{ {
DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;
} }
timing_t timing_counter_get(void) timing_t arch_timing_counter_get(void)
{ {
return (timing_t)z_arm_dwt_get_cycles(); return (timing_t)z_arm_dwt_get_cycles();
} }
uint64_t timing_cycles_get(volatile timing_t *const start, uint64_t arch_timing_cycles_get(volatile timing_t *const start,
volatile timing_t *const end) volatile timing_t *const end)
{ {
return (*end - *start); return (*end - *start);
} }
uint64_t timing_freq_get(void) uint64_t arch_timing_freq_get(void)
{ {
return z_arm_dwt_freq_get(); return z_arm_dwt_freq_get();
} }
uint64_t timing_cycles_to_ns(uint64_t cycles) uint64_t arch_timing_cycles_to_ns(uint64_t cycles)
{ {
return (cycles) * (NSEC_PER_USEC) / timing_freq_get_mhz(); return (cycles) * (NSEC_PER_USEC) / arch_timing_freq_get_mhz();
} }
uint64_t timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count)
{ {
return timing_cycles_to_ns(cycles) / count; return arch_timing_cycles_to_ns(cycles) / count;
} }
uint32_t timing_freq_get_mhz(void) uint32_t arch_timing_freq_get_mhz(void)
{ {
return (uint32_t)(timing_freq_get() / 1000000); return (uint32_t)(arch_timing_freq_get() / 1000000);
} }

View file

@ -8,46 +8,46 @@
#include <sys_clock.h> #include <sys_clock.h>
#include <timing/timing.h> #include <timing/timing.h>
void timing_init(void) void arch_timing_init(void)
{ {
} }
void timing_start(void) void arch_timing_start(void)
{ {
} }
void timing_stop(void) void arch_timing_stop(void)
{ {
} }
timing_t timing_counter_get(void) timing_t arch_timing_counter_get(void)
{ {
return k_cycle_get_32(); return k_cycle_get_32();
} }
uint64_t timing_cycles_get(volatile timing_t *const start, uint64_t arch_timing_cycles_get(volatile timing_t *const start,
volatile timing_t *const end) volatile timing_t *const end)
{ {
return (*end - *start); return (*end - *start);
} }
uint64_t timing_freq_get(void) uint64_t arch_timing_freq_get(void)
{ {
return sys_clock_hw_cycles_per_sec(); return sys_clock_hw_cycles_per_sec();
} }
uint64_t timing_cycles_to_ns(uint64_t cycles) uint64_t arch_timing_cycles_to_ns(uint64_t cycles)
{ {
return k_cyc_to_ns_floor64(cycles); return k_cyc_to_ns_floor64(cycles);
} }
uint64_t timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count)
{ {
return timing_cycles_to_ns(cycles) / count; return arch_timing_cycles_to_ns(cycles) / count;
} }
uint32_t timing_freq_get_mhz(void) uint32_t arch_timing_freq_get_mhz(void)
{ {
return (uint32_t)(timing_freq_get() / 1000000); return (uint32_t)(arch_timing_freq_get() / 1000000);
} }

View file

@ -20,46 +20,46 @@
<< 16) | \ << 16) | \
((uint32_t)IORD_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE)))) ((uint32_t)IORD_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE))))
void timing_init(void) void arch_timing_init(void)
{ {
} }
void timing_start(void) void arch_timing_start(void)
{ {
} }
void timing_stop(void) void arch_timing_stop(void)
{ {
} }
timing_t timing_counter_get(void) timing_t arch_timing_counter_get(void)
{ {
IOWR_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE, 10); IOWR_ALTERA_AVALON_TIMER_SNAPL(TIMER_0_BASE, 10);
return TIMING_INFO_OS_GET_TIME(); return TIMING_INFO_OS_GET_TIME();
} }
uint64_t timing_cycles_get(volatile timing_t *const start, uint64_t arch_timing_cycles_get(volatile timing_t *const start,
volatile timing_t *const end) volatile timing_t *const end)
{ {
return (*end - *start); return (*end - *start);
} }
uint64_t timing_freq_get(void) uint64_t arch_timing_freq_get(void)
{ {
return sys_clock_hw_cycles_per_sec(); return sys_clock_hw_cycles_per_sec();
} }
uint64_t timing_cycles_to_ns(uint64_t cycles) uint64_t arch_timing_cycles_to_ns(uint64_t cycles)
{ {
return k_cyc_to_ns_floor64(cycles); return k_cyc_to_ns_floor64(cycles);
} }
uint64_t timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count)
{ {
return timing_cycles_to_ns(cycles) / count; return arch_timing_cycles_to_ns(cycles) / count;
} }
uint32_t timing_freq_get_mhz(void) uint32_t arch_timing_freq_get_mhz(void)
{ {
return (uint32_t)(timing_freq_get() / 1000000); return (uint32_t)(arch_timing_freq_get() / 1000000);
} }

View file

@ -11,7 +11,7 @@
static uint64_t tsc_freq; static uint64_t tsc_freq;
void timing_x86_init(void) void arch_timing_x86_init(void)
{ {
uint32_t cyc_start = k_cycle_get_32(); uint32_t cyc_start = k_cycle_get_32();
uint64_t tsc_start = z_tsc_read(); uint64_t tsc_start = z_tsc_read();
@ -35,51 +35,52 @@ void timing_x86_init(void)
tsc_freq = (cyc_freq * dtsc) / dcyc; tsc_freq = (cyc_freq * dtsc) / dcyc;
} }
uint64_t timing_x86_freq_get(void) uint64_t arch_timing_x86_freq_get(void)
{ {
return tsc_freq; return tsc_freq;
} }
void timing_init(void) void arch_timing_init(void)
{ {
timing_x86_init(); arch_timing_x86_init();
} }
void timing_start(void)
void arch_timing_start(void)
{ {
} }
void timing_stop(void) void arch_timing_stop(void)
{ {
} }
timing_t timing_counter_get(void) timing_t arch_timing_counter_get(void)
{ {
return k_cycle_get_32(); return k_cycle_get_32();
} }
uint64_t timing_cycles_get(volatile timing_t *const start, uint64_t arch_timing_cycles_get(volatile timing_t *const start,
volatile timing_t *const end) volatile timing_t *const end)
{ {
return (*end - *start); return (*end - *start);
} }
uint64_t timing_freq_get(void) uint64_t arch_timing_freq_get(void)
{ {
return timing_x86_freq_get(); return arch_timing_x86_freq_get();
} }
uint64_t timing_cycles_to_ns(uint64_t cycles) uint64_t arch_timing_cycles_to_ns(uint64_t cycles)
{ {
return k_cyc_to_ns_floor64(cycles); return k_cyc_to_ns_floor64(cycles);
} }
uint64_t timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count)
{ {
return timing_cycles_to_ns(cycles) / count; return arch_timing_cycles_to_ns(cycles) / count;
} }
uint32_t timing_freq_get_mhz(void) uint32_t arch_timing_freq_get_mhz(void)
{ {
return (uint32_t)(timing_freq_get() / 1000000); return (uint32_t)(arch_timing_freq_get() / 1000000);
} }

View file

@ -845,6 +845,109 @@ size_t arch_cache_line_size_get(void);
#endif #endif
/** @} */ /** @} */
#ifdef CONFIG_TIMING_FUNCTIONS
#include <timing/types.h>
/**
* @ingroup arch-interface timing_api
*/
/**
* @brief Initialize the timing subsystem.
*
* Perform the necessary steps to initialize the timing subsystem.
*
* @see timing_init()
*/
void arch_timing_init(void);
/**
* @brief Signal the start of the timing information gathering.
*
* Signal to the timing subsystem that timing information
* will be gathered from this point forward.
*
* @see timing_start()
*/
void arch_timing_start(void);
/**
* @brief Signal the end of the timing information gathering.
*
* Signal to the timing subsystem that timing information
* is no longer being gathered from this point forward.
*
* @see timing_stop()
*/
void arch_timing_stop(void);
/**
* @brief Return timing counter.
*
* @return Timing counter.
*
* @see timing_counter_get()
*/
timing_t arch_timing_counter_get(void);
/**
* @brief Get number of cycles between @p start and @p end.
*
* For some architectures or SoCs, the raw numbers from counter
* need to be scaled to obtain actual number of cycles.
*
* @param start Pointer to counter at start of a measured execution.
* @param end Pointer to counter at stop of a measured execution.
* @return Number of cycles between start and end.
*
* @see timing_cycles_get()
*/
uint64_t arch_timing_cycles_get(volatile timing_t *const start,
volatile timing_t *const end);
/**
* @brief Get frequency of counter used (in Hz).
*
* @return Frequency of counter used for timing in Hz.
*
* @see timing_freq_get()
*/
uint64_t arch_timing_freq_get(void);
/**
* @brief Convert number of @p cycles into nanoseconds.
*
* @param cycles Number of cycles
* @return Converted time value
*
* @see timing_cycles_to_ns()
*/
uint64_t arch_timing_cycles_to_ns(uint64_t cycles);
/**
* @brief Convert number of @p cycles into nanoseconds with averaging.
*
* @param cycles Number of cycles
* @param count Times of accumulated cycles to average over
* @return Converted time value
*
* @see timing_cycles_to_ns_avg()
*/
uint64_t arch_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count);
/**
* @brief Get frequency of counter used (in MHz).
*
* @return Frequency of counter used for timing in MHz.
*
* @see timing_freq_get_mhz()
*/
uint32_t arch_timing_freq_get_mhz(void);
/* @} */
#endif /* CONFIG_TIMING_FUNCTIONS */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View file

@ -7,7 +7,30 @@
#ifndef ZEPHYR_INCLUDE_TIMING_TIMING_H_ #ifndef ZEPHYR_INCLUDE_TIMING_TIMING_H_
#define ZEPHYR_INCLUDE_TIMING_TIMING_H_ #define ZEPHYR_INCLUDE_TIMING_TIMING_H_
#include <kernel.h> #include <sys/arch_interface.h>
#include <timing/types.h>
void soc_timing_init(void);
void soc_timing_start(void);
void soc_timing_stop(void);
timing_t soc_timing_counter_get(void);
uint64_t soc_timing_cycles_get(volatile timing_t *const start,
volatile timing_t *const end);
uint64_t soc_timing_freq_get(void);
uint64_t soc_timing_cycles_to_ns(uint64_t cycles);
uint64_t soc_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count);
uint32_t soc_timing_freq_get_mhz(void);
void board_timing_init(void);
void board_timing_start(void);
void board_timing_stop(void);
timing_t board_timing_counter_get(void);
uint64_t board_timing_cycles_get(volatile timing_t *const start,
volatile timing_t *const end);
uint64_t board_timing_freq_get(void);
uint64_t board_timing_cycles_to_ns(uint64_t cycles);
uint64_t board_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count);
uint32_t board_timing_freq_get_mhz(void);
/** /**
@ -17,8 +40,6 @@
*/ */
typedef uint64_t timing_t;
/** /**
* @brief Initialize the timing subsystem. * @brief Initialize the timing subsystem.
* *
@ -47,7 +68,16 @@ void timing_stop(void);
* *
* @return Timing counter. * @return Timing counter.
*/ */
timing_t timing_counter_get(void); static inline timing_t timing_counter_get(void)
{
#if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
return board_timing_counter_get();
#elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
return soc_timing_counter_get();
#else
return arch_timing_counter_get();
#endif
}
/** /**
* @brief Get number of cycles between @p start and @p end. * @brief Get number of cycles between @p start and @p end.
@ -59,15 +89,33 @@ timing_t timing_counter_get(void);
* @param end Pointer to counter at stop of a measured execution. * @param end Pointer to counter at stop of a measured execution.
* @return Number of cycles between start and end. * @return Number of cycles between start and end.
*/ */
uint64_t timing_cycles_get(volatile timing_t *const start, static inline uint64_t timing_cycles_get(volatile timing_t *const start,
volatile timing_t *const end); volatile timing_t *const end)
{
#if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
return board_timing_cycles_get(start, end);
#elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
return soc_timing_cycles_get(start, end);
#else
return arch_timing_cycles_get(start, end);
#endif
}
/** /**
* @brief Get frequency of counter used (in Hz). * @brief Get frequency of counter used (in Hz).
* *
* @return Frequency of counter used for timing in Hz. * @return Frequency of counter used for timing in Hz.
*/ */
uint64_t timing_freq_get(void); static inline uint64_t timing_freq_get(void)
{
#if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
return board_timing_freq_get();
#elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
return soc_timing_freq_get();
#else
return arch_timing_freq_get();
#endif
}
/** /**
* @brief Convert number of @p cycles into nanoseconds. * @brief Convert number of @p cycles into nanoseconds.
@ -75,16 +123,50 @@ uint64_t timing_freq_get(void);
* @param cycles Number of cycles * @param cycles Number of cycles
* @return Converted time value * @return Converted time value
*/ */
uint64_t timing_cycles_to_ns(uint64_t cycles); static inline uint64_t timing_cycles_to_ns(uint64_t cycles)
{
#if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
return board_timing_cycles_to_ns(cycles);
#elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
return soc_timing_cycles_to_ns(cycles);
#else
return arch_timing_cycles_to_ns(cycles);
#endif
}
uint64_t timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count); /**
* @brief Convert number of @p cycles into nanoseconds with averaging.
*
* @param cycles Number of cycles
* @param count Times of accumulated cycles to average over
* @return Converted time value
*/
static inline uint64_t timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count)
{
#if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
return board_timing_cycles_to_ns_avg(cycles, count);
#elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
return soc_timing_cycles_to_ns_avg(cycles, count);
#else
return arch_timing_cycles_to_ns_avg(cycles, count);
#endif
}
/** /**
* @brief Get frequency of counter used (in MHz). * @brief Get frequency of counter used (in MHz).
* *
* @return Frequency of counter used for timing in MHz. * @return Frequency of counter used for timing in MHz.
*/ */
uint32_t timing_freq_get_mhz(void); static inline uint32_t timing_freq_get_mhz(void)
{
#if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
return board_timing_freq_get_mhz();
#elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
return soc_timing_freq_get_mhz();
#else
return arch_timing_freq_get_mhz();
#endif
}
/** /**
* @} * @}

12
include/timing/types.h Normal file
View file

@ -0,0 +1,12 @@
/*
* Copyright (c) 2020 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_TIMING_TYPES_H_
#define ZEPHYR_INCLUDE_TIMING_TYPES_H_
typedef uint64_t timing_t;
#endif /* ZEPHYR_INCLUDE_TIMING_TYPES_H_ */

View file

@ -10,7 +10,7 @@
#include <timing/timing.h> #include <timing/timing.h>
#include <soc.h> #include <soc.h>
void timing_init(void) void soc_timing_init(void)
{ {
/* Setup counter */ /* Setup counter */
B32TMR1_REGS->CTRL = MCHP_BTMR_CTRL_ENABLE | B32TMR1_REGS->CTRL = MCHP_BTMR_CTRL_ENABLE |
@ -24,43 +24,43 @@ void timing_init(void)
B32TMR1_REGS->STS = 1; /* Clear interrupt */ B32TMR1_REGS->STS = 1; /* Clear interrupt */
} }
void timing_start(void) void soc_timing_start(void)
{ {
B32TMR1_REGS->CTRL |= MCHP_BTMR_CTRL_START; B32TMR1_REGS->CTRL |= MCHP_BTMR_CTRL_START;
} }
void timing_stop(void) void soc_timing_stop(void)
{ {
B32TMR1_REGS->CTRL &= ~MCHP_BTMR_CTRL_START; B32TMR1_REGS->CTRL &= ~MCHP_BTMR_CTRL_START;
} }
timing_t timing_counter_get(void) timing_t soc_timing_counter_get(void)
{ {
return B32TMR1_REGS->CNT; return B32TMR1_REGS->CNT;
} }
uint64_t timing_cycles_get(volatile timing_t *const start, uint64_t soc_timing_cycles_get(volatile timing_t *const start,
volatile timing_t *const end) volatile timing_t *const end)
{ {
return (*end - *start); return (*end - *start);
} }
uint64_t timing_freq_get(void) uint64_t soc_timing_freq_get(void)
{ {
return CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; return CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
} }
uint64_t timing_cycles_to_ns(uint64_t cycles) uint64_t soc_timing_cycles_to_ns(uint64_t cycles)
{ {
return (cycles) * (NSEC_PER_SEC) / (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); return (cycles) * (NSEC_PER_SEC) / (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
} }
uint64_t timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) uint64_t soc_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count)
{ {
return (uint32_t)timing_cycles_to_ns(cycles) / count; return (uint32_t)soc_timing_cycles_to_ns(cycles) / count;
} }
uint32_t timing_freq_get_mhz(void) uint32_t soc_timing_freq_get_mhz(void)
{ {
return (uint32_t)(timing_freq_get() / 1000000); return (uint32_t)(soc_timing_freq_get() / 1000000);
} }

View file

@ -33,7 +33,7 @@ config SYS_POWER_MANAGEMENT
config BUILD_OUTPUT_HEX config BUILD_OUTPUT_HEX
default y default y
if !CORTEX_M_DWT if !CORTEX_M_DWT && NRF_RTC_TIMER
config SOC_HAS_TIMING_FUNCTIONS config SOC_HAS_TIMING_FUNCTIONS
default y default y
endif endif

View file

@ -14,7 +14,7 @@
#define CYCLES_PER_SEC (16000000 / (1 << NRF_TIMER2->PRESCALER)) #define CYCLES_PER_SEC (16000000 / (1 << NRF_TIMER2->PRESCALER))
void timing_init(void) void soc_timing_init(void)
{ {
NRF_TIMER2->TASKS_CLEAR = 1; /* Clear Timer */ NRF_TIMER2->TASKS_CLEAR = 1; /* Clear Timer */
NRF_TIMER2->MODE = 0; /* Timer Mode */ NRF_TIMER2->MODE = 0; /* Timer Mode */
@ -26,23 +26,23 @@ void timing_init(void)
#endif #endif
} }
void timing_start(void) void soc_timing_start(void)
{ {
NRF_TIMER2->TASKS_START = 1; NRF_TIMER2->TASKS_START = 1;
} }
void timing_stop(void) void soc_timing_stop(void)
{ {
NRF_TIMER2->TASKS_STOP = 1; /* Stop Timer */ NRF_TIMER2->TASKS_STOP = 1; /* Stop Timer */
} }
timing_t timing_counter_get(void) timing_t soc_timing_counter_get(void)
{ {
NRF_TIMER2->TASKS_CAPTURE[0] = 1; NRF_TIMER2->TASKS_CAPTURE[0] = 1;
return NRF_TIMER2->CC[0] * ((SystemCoreClock) / CYCLES_PER_SEC); return NRF_TIMER2->CC[0] * ((SystemCoreClock) / CYCLES_PER_SEC);
} }
uint64_t timing_cycles_get(volatile timing_t *const start, uint64_t soc_timing_cycles_get(volatile timing_t *const start,
volatile timing_t *const end) volatile timing_t *const end)
{ {
#if defined(CONFIG_SOC_SERIES_NRF51X) #if defined(CONFIG_SOC_SERIES_NRF51X)
@ -57,24 +57,24 @@ uint64_t timing_cycles_get(volatile timing_t *const start,
#endif #endif
} }
uint64_t timing_freq_get(void) uint64_t soc_timing_freq_get(void)
{ {
return SystemCoreClock; return SystemCoreClock;
} }
uint64_t timing_cycles_to_ns(uint64_t cycles) uint64_t soc_timing_cycles_to_ns(uint64_t cycles)
{ {
return (cycles) * (NSEC_PER_SEC) / (SystemCoreClock); return (cycles) * (NSEC_PER_SEC) / (SystemCoreClock);
} }
uint64_t timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count) uint64_t soc_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count)
{ {
return timing_cycles_to_ns(cycles) / count; return soc_timing_cycles_to_ns(cycles) / count;
} }
uint32_t timing_freq_get_mhz(void) uint32_t soc_timing_freq_get_mhz(void)
{ {
return (uint32_t)(timing_freq_get() / 1000000); return (uint32_t)(soc_timing_freq_get() / 1000000);
} }
#endif #endif

View file

@ -24,3 +24,4 @@ add_subdirectory(testsuite)
add_subdirectory(tracing) add_subdirectory(tracing)
add_subdirectory_ifdef(CONFIG_JWT jwt) add_subdirectory_ifdef(CONFIG_JWT jwt)
add_subdirectory(canbus) add_subdirectory(canbus)
add_subdirectory_ifdef(CONFIG_TIMING_FUNCTIONS timing)

View file

@ -0,0 +1,6 @@
# Copyright (c) 2020 Intel Corporation.
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
zephyr_library_sources(timing.c)

60
subsys/timing/timing.c Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (c) 2020 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <kernel.h>
#include <sys/atomic.h>
#include <timing/timing.h>
static bool has_inited;
static atomic_val_t started_ref;
void timing_init(void)
{
if (has_inited) {
return;
}
#if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
board_timing_init();
#elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
soc_timing_init();
#else
arch_timing_init();
#endif
has_inited = true;
}
void timing_start(void)
{
if (atomic_inc(&started_ref) != 0) {
return;
}
#if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
board_timing_start();
#elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
soc_timing_start();
#else
arch_timing_start();
#endif
}
void timing_stop(void)
{
if (atomic_dec(&started_ref) > 1) {
return;
}
#if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
board_timing_stop();
#elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
soc_timing_stop();
#else
arch_timing_stop();
#endif
}