summaryrefslogtreecommitdiffstats
path: root/cpukit/sapi/src/profilingiterate.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-03-10 10:04:09 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-03-14 08:46:49 +0100
commitf980561ee073a7f24f65ed572852fa96edfa1708 (patch)
treea2e62dd469acbe201388c9b8a3e0ebd9d7277e9f /cpukit/sapi/src/profilingiterate.c
parentsapi: Add SMP lock profiling app. level data (diff)
downloadrtems-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/src/profilingiterate.c')
-rw-r--r--cpukit/sapi/src/profilingiterate.c61
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);
}