#ifndef lib_perf_h #define lib_perf_h /* Cesar project {{{ * * Copyright (C) 2009 Spidcom * * <<>> * * }}} */ /** * \file lib/perf.h * \brief Performance measure tool. * \ingroup lib * * This can be used to instrument code in order to measure its performance. * * The user must define a configuration item which starts with CONFIG_PERF. * It will be used to conditionally include the measurement code for a * particular piece of code. * * Results can be stored in a trace buffer. * * The CONFIG_PERF item (without suffix) is the global switch to disable all * performance measurement. */ /* Include all user defined configuration items. */ #include "config/perf.h" #if CONFIG_PERF # include "lib/trace.h" # include "hal/arch/time.h" /** * To be used at begin of function to measure its execution time. * \param config configuration item suffix to activate this measurement */ # define PERF_FUNC_BEGIN(config) \ PASTE_EXPAND (PERF_FUNC_BEGIN_, CONFIG_PERF_ ## config) () # define PERF_FUNC_BEGIN_0() # define PERF_FUNC_BEGIN_1() \ TRACE_FAST_SHORT (PERF_TRACE_, &perf_global.trace, FUNC_BEGIN, ARCH_TIME, \ __PRETTY_FUNCTION__) /** * To be used inside a function to measure its execution time. * \param config configuration item suffix to activate this measurement * \param step step identifier */ # define PERF_FUNC_STEP(config, step) \ PASTE_EXPAND (PERF_FUNC_STEP_, CONFIG_PERF_ ## config) (#step) # define PERF_FUNC_STEP_0(step) # define PERF_FUNC_STEP_1(step) \ TRACE_FAST_SHORT (PERF_TRACE_, &perf_global.trace, FUNC_STEP, ARCH_TIME, \ __PRETTY_FUNCTION__, step) /** * To be used at end of function to measure its execution time. * \param config configuration item suffix to activate this measurement */ # define PERF_FUNC_END(config) \ PASTE_EXPAND (PERF_FUNC_END_, CONFIG_PERF_ ## config) () # define PERF_FUNC_END_0() # define PERF_FUNC_END_1() \ TRACE_FAST_SHORT (PERF_TRACE_, &perf_global.trace, FUNC_END, ARCH_TIME, \ __PRETTY_FUNCTION__) /** * Can be used to measure a small code chunk: * * \code * uint i; * u32 start = PERF_TIME; * for (i = 0; i = MANY; i++) * run_my_code (); * u32 stop = PERF_TIME; * test_verbose_print ("run_my_code: %d us/%d", * (stop - start) / PERF_FREQ_MHZ, MANY); * \endcode */ # define PERF_TIME ARCH_TIME /** Frequency of the measurement clock. */ # define PERF_FREQ_MHZ ARCH_TIME_FREQ_MHZ /** Context. */ struct perf_t { #if CONFIG_TRACE /** Trace performance results. */ trace_buffer_t trace; #endif /* CONFIG_TRACE */ }; typedef struct perf_t perf_t; /** Global context. */ extern perf_t perf_global; /** Trace events. */ enum { PERF_TRACE_FUNC_BEGIN, PERF_TRACE_FUNC_STEP, PERF_TRACE_FUNC_END, }; BEGIN_DECLS /** * Initialise this module. */ void perf_init (void); /** * Uninitialise this module. */ void perf_uninit (void); END_DECLS #else # define PERF_FUNC_BEGIN(config) # define PERF_FUNC_STEP(config, step) # define PERF_FUNC_END(config) # define perf_init() # define perf_uninit() #endif #endif /* lib_perf_h */