Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | /*
* Copyright (c) 2017 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <timestamp.h>
#define CALCULATE_TIME(special_char, profile, name) \
{ \
total_##profile##_##name##_time = CYCLES_TO_NS( \
special_char##profile##_##name##_end_time - \
special_char##profile##_##name##_start_time); \
}
#define DECLARE_VAR(profile, name) \
u64_t total_##profile##_##name##_time;
/* NRF RTC TIMER runs ar very slow rate (32KHz), So in order to measure
* Kernel starts a dedicated timer to measure kernel stats.
*/
#if defined(CONFIG_NRF_RTC_TIMER)
#define NANOSECS_PER_SEC 1000000000
#define CYCLES_PER_SEC (16000000/(1 << NRF_TIMER2->PRESCALER))
/* To get current count of timer, first 1 need to be written into
* Capture Register and Current Count will be copied into corresponding
* current count register.
*/
#define TIMING_INFO_PRE_READ() (NRF_TIMER2->TASKS_CAPTURE[0] = 1)
#define TIMING_INFO_OS_GET_TIME() (NRF_TIMER2->CC[0])
#define TIMING_INFO_GET_TIMER_VALUE() TIMING_INFO_GET_CURRENT_TIME()
#define CYCLES_TO_NS(x) ((x) * (NANOSECS_PER_SEC/CYCLES_PER_SEC))
#define PRINT_STATS(x, y, z) PRINT_F(x, (y*((SystemCoreClock)/ \
CYCLES_PER_SEC)), z)
/* Configure Timer parameters */
static inline void benchmark_timer_init(void)
{
NRF_TIMER2->TASKS_CLEAR = 1; /* Clear Timer */
NRF_TIMER2->MODE = 0; /* Timer Mode */
NRF_TIMER2->PRESCALER = 0; /* 16M Hz */
NRF_TIMER2->BITMODE = 3; /* 32 - bit */
}
/* Stop the timer */
static inline void benchmark_timer_stop(void)
{
NRF_TIMER2->TASKS_STOP = 1; /* Stop Timer */
}
/*Start the timer */
static inline void benchmark_timer_start(void)
{
NRF_TIMER2->TASKS_START = 1; /* Start Timer */
}
/* Get Core Frequency in MHz */
static inline u32_t get_core_freq_MHz(void)
{
return SystemCoreClock/1000000;
}
#else /* All other architectures */
/* Done because weak attribute doesn't work on static inline. */
static inline void benchmark_timer_init(void) { }
static inline void benchmark_timer_stop(void) { }
static inline void benchmark_timer_start(void) { }
#define TIMING_INFO_PRE_READ()
#define TIMING_INFO_OS_GET_TIME() k_cycle_get_32()
#ifdef CONFIG_ARM
#define TIMING_INFO_GET_TIMER_VALUE() SysTick->VAL
#endif /* CONFIG_ARM */
#define CYCLES_TO_NS(x) SYS_CLOCK_HW_CYCLES_TO_NS(x)
/* Dummy functions for timer */
/* Get Core Frequency in MHz */
static inline u32_t get_core_freq_MHz(void)
{
return (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC/1000000);
}
#define PRINT_STATS(x, y, z) PRINT_F(x, y, z)
#endif /* CONFIG_NRF_RTC_TIMER */
/* Function prototypes */
void system_thread_bench(void);
void yield_bench(void);
void heap_malloc_free_bench(void);
void semaphore_bench(void);
void mutex_bench(void);
void msg_passing_bench(void);
/* External variables */
extern u64_t __start_swap_time;
extern u64_t __end_swap_time;
extern u64_t __start_intr_time;
extern u64_t __end_intr_time;
extern u64_t __start_tick_time;
extern u64_t __end_tick_time;
/* PRINT_F
* Macro to print a formatted output string. fprintf is used when
* Assumed that sline character array of SLINE_LEN + 1 characters
* is defined in the main file
*/
/* #define CSV_FORMAT_OUTPUT */
/* printf format defines. */
#ifdef CSV_FORMAT_OUTPUT
#define FORMAT "%-45s,%4u,%5u\n"
#else
#define FORMAT "%-45s:%4u cycles , %5u ns\n"
#endif
#include <stdio.h>
#define GET_2ND_ARG(first, second, ...) (second)
#define GET_3ND_ARG(first, second, third, ...) (third)
/* Enable this macro to print all the measurements.
* Note: Some measurements in few architectures are not valid
*/
/* #define PRINT_ALL_MEASUREMENTS */
#ifndef PRINT_ALL_MEASUREMENTS
/*If the measured cycles is greater than 10000 then one of the following is
* possible.
* 1. the selected measurement is not supported in the architecture
* 2. The measurement went wrong somewhere.(less likely to happen)
*/
#define PRINT_F(...) \
{ \
if ((GET_2ND_ARG(__VA_ARGS__) <= 20000) && \
(GET_2ND_ARG(__VA_ARGS__) != 0)) { \
snprintf(sline, 254, FORMAT, ##__VA_ARGS__); \
TC_PRINT("%s", sline); \
} \
}
#else
/* Prints all outputs*/
#define PRINT_F(...) \
{ \
snprintf(sline, 254, FORMAT, ##__VA_ARGS__); \
TC_PRINT("%s", sline); \
}
#endif
/* If we are using x86 based controller we tend to read the tsc value which is
* always incrementing i.e count up counter.
* If we are using the ARM based controllers the systick is a
* count down counter.
* If we are using nrf SOC, we are using external timer which always increments
* ie count up counter.
* Hence to calculate the cycles taken up by the code we need to adjust the
* values accordingly.
*
* NOTE: Needed only when reading value from end of swap operation
*/
#if CONFIG_ARM
#if defined(CONFIG_SOC_FAMILY_NRF)
#define SUBTRACT_CLOCK_CYCLES(val) (val)
#else
#define SUBTRACT_CLOCK_CYCLES(val) (SysTick->LOAD - (u32_t) val)
#endif /* CONFIG_SOC_FAMILY_NRF */
#else
#define SUBTRACT_CLOCK_CYCLES(val) (val)
#endif /* CONFIG_ARM */
|