
#if 0

Sample code for declaring and calling debug_*_rt_trace_*()

These are debug functions that a kernel developer might want
to call to measure time intervals.  There are normally no callers of
these functions in the kernel source.

The functions are available if CONFIG_SNSC_RT_TRACE=y

Some of the debug_*_rt_trace_*() functions have unique features:

	debug_1_rt_trace_*()
	--------------------

	When CONFIG_SNSC_RT_TRACE_LOCK_STAT=y, data collection for the lock
	statistics enabled by CONFIG_LOCK_STAT=y (and reported in
	/proc/lock_stat) is controlled by debug_1_rt_trace_enter() and
	debug_1_rt_trace_exit().  Data collection is enabled by
	debug_1_rt_trace_enter() and disabled by debug_1_rt_trace_exit(),
	in addition to the control by /proc/sys/kernel/lock_stat.  Data
	collection is enabled only on the cpu that debug_1_rt_trace_enter()
	executes on.

	debug_5_rt_trace_*()
	--------------------

	When CONFIG_SNSC_5_RT_TRACE_WITH_PMU=y, PMU statistics are
	collected and reported for debug_5_rt_trace_*().

	When CONFIG_SNSC_5_RT_TRACE_WITH_PMU_HISTOGRAM=y, PMU statistics are
	collected and reported for debug_5_rt_trace_*() in histogram form.

	When CONFIG_SNSC_5_RT_TRACE_PMU_TRACE=y, for each call of
	debug_5_rt_trace_enter() and debug_5_rt_trace_exit() a trace event
	of the PMU data is reported.

The measurements are read from:

	/proc/rt_debug_1
	/proc/rt_debug_2
	/proc/rt_debug_3
	/proc/rt_debug_4
	/proc/rt_debug_5
	/proc/rt_debug_6

All of the measurements are enabled by a single file:

	echo 1 >/proc/sys/kernel/rt_debug_enable

All of the measurements are disabled by a single file:

	echo 0 >/proc/sys/kernel/rt_debug_enable

The measurements are reset by:

	echo 0 > /proc/rt_debug_1
	echo 0 > /proc/rt_debug_2
	echo 0 > /proc/rt_debug_3
	echo 0 > /proc/rt_debug_4
	echo 0 > /proc/rt_debug_5
	echo 0 > /proc/rt_debug_6

Interpretting the measurement reports:

   An example report is:

      #adjusted do_local_timer()  cpu 0 min,avg,max,count : 102 143  318    2778
      #calibrate min,avg,max   : 1 1 3
      #overhead  min,avg,max   : 4 4 6
      #usecs           samples
        103                  1
        104                  2
        105                  1
        106                 12
        107                 20

   The name following "#adjusted" can be set by calling rt_debug_*_init().
   Otherwise is will be rt_debug_*.

   An attempt is made to subtract the cost of zero path length measurement
   from the min, avg, and max.  The cost is _not_ subtracted from the
   histogram data.  The amount subtracted is reported on the "#calibrate" line.
   The values in the "#calibrate" line are measured by calling the measurement
   functions with no intervening code:

	debug_1_rt_trace_enter()
	debug_1_rt_trace_exit()

   A common use case is to have nested measurements:

	debug_1_rt_trace_enter();
		debug_2_rt_trace_enter();
		... some interesting code ...
		debug_2_rt_trace_exit();
		debug_3_rt_trace_enter();
		... some interesting code ...
		debug_3_rt_trace_exit();
	debug_1_rt_trace_exit();

   No attempt is made to automatically subtrace the overhead from the data,
   but the cost of a debug_*_rt_trace_enter() and a debug_*_rt_trace_exit()
   is reported by the "#overhead" line.  This overhead is adjusted by the
   "#calibration" values.  The values in the "#overhead" line are measured
   by calling the measurement functions to measure debug_2_rt_trace_*():

	debug_1_rt_trace_enter();
		debug_2_rt_trace_enter();
		debug_2_rt_trace_exit();
	debug_1_rt_trace_exit();

   Note that the "#calibrate" and "#overhead" values are not exact, but are
   just an approximation.

   The histogram data is collected if CONFIG_SNSC_LITE_IRQSOFF_DEBUG_HISTOGRAM=y.

#endif



#include <linux/rt_trace_lite.h>


#if 0

/*
 * The default measurement name reported in /proc/rt_debug_* is rt_debug_*.
 * The measurement name can be changed by the following functions.
 */

static int rt_debug_1_init(void)
{
	rt_debug_1_init_name("zzz() ");

	return 0;
}
__initcall(rt_debug_1_init);


static int rt_debug_2_init(void)
{
	rt_debug_2_init_name("zzz() ");

	return 0;
}
__initcall(rt_debug_2_init);


static int rt_debug_3_init(void)
{
	rt_debug_3_init_name("zzz() ");

	return 0;
}
__initcall(rt_debug_3_init);


static int rt_debug_4_init(void)
{
	rt_debug_4_init_name("zzz() ");

	return 0;
}
__initcall(rt_debug_4_init);


static int rt_debug_5_init(void)
{
	rt_debug_5_init_name("zzz() ");

	return 0;
}
__initcall(rt_debug_5_init);


static int rt_debug_6_init(void)
{
	rt_debug_6_init_name("zzz() ");

	return 0;
}
__initcall(rt_debug_6_init);
#endif


#if 0
	/*
	 * To collect data about a code path, surround the path with
	 * debug_*_trace_enter() and debug_*_trace_exit().
	 *
	 * The resulting data will only be valid if no context switch or
	 * interrupt occurs between the enter() and the exit().  Thus this
	 * instrumentation is most useful when interrupts are disabled.
	 */

	debug_1_rt_trace_enter();
	debug_1_rt_trace_exit();

	debug_2_rt_trace_enter();
	debug_2_rt_trace_exit();

	debug_3_rt_trace_enter();
	debug_3_rt_trace_exit();

	debug_4_rt_trace_enter();
	debug_4_rt_trace_exit();

	debug_5_rt_trace_enter();
	debug_5_rt_trace_exit();

	debug_6_rt_trace_enter();
	debug_6_rt_trace_exit();


	/*
	 * When CONFIG_SNSC_5_RT_TRACE_PMU_TRACE=y, trace events containing
	 * PMU data are created.  There are two user defined fields (data_1
	 * and data_2) in the trace event that are initialized to zero by
	 * debug_5_rt_trace_enter(), then modified by:
	 *
	 *   rt_debug_5_data_1_set()   rt_debug_5_data_2_set()
	 *   rt_debug_5_data_1_or()    rt_debug_5_data_2_or()
	 *   rt_debug_5_data_1_add()   rt_debug_5_data_2_add()
	 *
	 * data_1 and data_2 can be used for any arbitrary purpose or meaning
	 * as desired by the author of temporary debugging code.
	 *
	 * There is additional support to use data_1 as a bit map to indicate
	 * whether a specific event or condition has occurred.  See patch
	 * example-use-of-5_rt_trace_pmu_trace-data_1-20101002.patch for an
	 * example of using data_1 to indicate which of several possible code
	 * paths were hit.
	 */

	/*
	 * A measured code path might be called from more than one place.
	 * A trick to only measure the path when called from a specific
	 * place is to use a flag, as follows:
	 */

DEFINE_PER_CPU(int, rt_trace_in_window);
	__get_cpu_var(rt_trace_in_window) = 1;
	debug_1_rt_trace_enter();

	debug_1_rt_trace_exit();
	__get_cpu_var(rt_trace_in_window) = 0;


extern DEFINE_PER_CPU(int, rt_trace_in_window);

	if (__get_cpu_var(rt_trace_in_window))
		debug_1_rt_trace_enter();
	if (__get_cpu_var(rt_trace_in_window))
		debug_1_rt_trace_exit();

	if (__get_cpu_var(rt_trace_in_window))
		debug_2_rt_trace_enter();
	if (__get_cpu_var(rt_trace_in_window))
		debug_2_rt_trace_exit();

	if (__get_cpu_var(rt_trace_in_window))
		debug_3_rt_trace_enter();
	if (__get_cpu_var(rt_trace_in_window))
		debug_3_rt_trace_exit();

	if (__get_cpu_var(rt_trace_in_window))
		debug_4_rt_trace_enter();
	if (__get_cpu_var(rt_trace_in_window))
		debug_4_rt_trace_exit();

	if (__get_cpu_var(rt_trace_in_window))
		debug_5_rt_trace_enter();
	if (__get_cpu_var(rt_trace_in_window))
		debug_5_rt_trace_exit();

	if (__get_cpu_var(rt_trace_in_window))
		debug_6_rt_trace_enter();
	if (__get_cpu_var(rt_trace_in_window))
		debug_6_rt_trace_exit();
#endif
