diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-03-10 10:04:09 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2014-03-14 08:46:49 +0100 |
commit | f980561ee073a7f24f65ed572852fa96edfa1708 (patch) | |
tree | a2e62dd469acbe201388c9b8a3e0ebd9d7277e9f /cpukit/sapi | |
parent | sapi: Add SMP lock profiling app. level data (diff) | |
download | rtems-f980561ee073a7f24f65ed572852fa96edfa1708.tar.bz2 |
score: Add per-CPU profiling
Add per-CPU profiling stats API. Implement the thread dispatch disable
level profiling. The interrupt profiling must be implemented in CPU
port specific parts (mostly assembler code). Add a support function
_Profiling_Outer_most_interrupt_entry_and_exit() for this purpose.
Diffstat (limited to 'cpukit/sapi')
-rw-r--r-- | cpukit/sapi/src/profilingiterate.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/cpukit/sapi/src/profilingiterate.c b/cpukit/sapi/src/profilingiterate.c index e528932db9..28c06a4689 100644 --- a/cpukit/sapi/src/profilingiterate.c +++ b/cpukit/sapi/src/profilingiterate.c @@ -17,10 +17,71 @@ #endif #include <rtems/profiling.h> +#include <rtems/counter.h> +#include <rtems.h> + +#include <string.h> + +static void per_cpu_stats_iterate( + rtems_profiling_visitor visitor, + void *visitor_arg, + rtems_profiling_data *data +) +{ +#ifdef RTEMS_PROFILING + uint32_t n = rtems_smp_get_processor_count(); + uint32_t i; + + memset(data, 0, sizeof(*data)); + data->header.type = RTEMS_PROFILING_PER_CPU; + for (i = 0; i < n; ++i) { + const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index(i); + const Per_CPU_Stats *stats = &per_cpu->Stats; + rtems_profiling_per_cpu *per_cpu_data = &data->per_cpu; + + per_cpu_data->processor_index = i; + + per_cpu_data->max_thread_dispatch_disabled_time = + rtems_counter_ticks_to_nanoseconds( + stats->max_thread_dispatch_disabled_time + ); + + per_cpu_data->max_interrupt_time = + rtems_counter_ticks_to_nanoseconds(stats->max_interrupt_time); + + per_cpu_data->max_interrupt_delay = + rtems_counter_ticks_to_nanoseconds(stats->max_interrupt_delay); + + per_cpu_data->thread_dispatch_disabled_count = + stats->thread_dispatch_disabled_count; + + per_cpu_data->total_thread_dispatch_disabled_time = + rtems_counter_ticks_to_nanoseconds( + stats->total_thread_dispatch_disabled_time + ); + + per_cpu_data->interrupt_count = stats->interrupt_count; + + per_cpu_data->total_interrupt_time = + rtems_counter_ticks_to_nanoseconds( + stats->total_interrupt_time + ); + + (*visitor)(visitor_arg, data); + } +#else + (void) visitor; + (void) visitor_arg; + (void) data; +#endif +} void rtems_profiling_iterate( rtems_profiling_visitor visitor, void *visitor_arg ) { + rtems_profiling_data data; + + per_cpu_stats_iterate(visitor, visitor_arg, &data); } |