1 | /* |
---|
2 | * Copyright (c) 2014 embedded brains GmbH. All rights reserved. |
---|
3 | * |
---|
4 | * embedded brains GmbH |
---|
5 | * Dornierstr. 4 |
---|
6 | * 82178 Puchheim |
---|
7 | * Germany |
---|
8 | * <rtems@embedded-brains.de> |
---|
9 | * |
---|
10 | * The license and distribution terms for this file may be |
---|
11 | * found in the file LICENSE in this distribution or at |
---|
12 | * http://www.rtems.org/license/LICENSE. |
---|
13 | */ |
---|
14 | |
---|
15 | #ifdef HAVE_CONFIG_H |
---|
16 | #include "config.h" |
---|
17 | #endif |
---|
18 | |
---|
19 | #include <rtems/profiling.h> |
---|
20 | #include <rtems/counter.h> |
---|
21 | #include <rtems/score/smplock.h> |
---|
22 | #include <rtems.h> |
---|
23 | |
---|
24 | #include <string.h> |
---|
25 | |
---|
26 | static void per_cpu_stats_iterate( |
---|
27 | rtems_profiling_visitor visitor, |
---|
28 | void *visitor_arg, |
---|
29 | rtems_profiling_data *data |
---|
30 | ) |
---|
31 | { |
---|
32 | #ifdef RTEMS_PROFILING |
---|
33 | uint32_t n = rtems_get_processor_count(); |
---|
34 | uint32_t i; |
---|
35 | |
---|
36 | memset(data, 0, sizeof(*data)); |
---|
37 | data->header.type = RTEMS_PROFILING_PER_CPU; |
---|
38 | for (i = 0; i < n; ++i) { |
---|
39 | const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index(i); |
---|
40 | const Per_CPU_Stats *stats = &per_cpu->Stats; |
---|
41 | rtems_profiling_per_cpu *per_cpu_data = &data->per_cpu; |
---|
42 | |
---|
43 | per_cpu_data->processor_index = i; |
---|
44 | |
---|
45 | per_cpu_data->max_thread_dispatch_disabled_time = |
---|
46 | rtems_counter_ticks_to_nanoseconds( |
---|
47 | stats->max_thread_dispatch_disabled_time |
---|
48 | ); |
---|
49 | |
---|
50 | per_cpu_data->max_interrupt_time = |
---|
51 | rtems_counter_ticks_to_nanoseconds(stats->max_interrupt_time); |
---|
52 | |
---|
53 | per_cpu_data->max_interrupt_delay = |
---|
54 | rtems_counter_ticks_to_nanoseconds(stats->max_interrupt_delay); |
---|
55 | |
---|
56 | per_cpu_data->thread_dispatch_disabled_count = |
---|
57 | stats->thread_dispatch_disabled_count; |
---|
58 | |
---|
59 | per_cpu_data->total_thread_dispatch_disabled_time = |
---|
60 | rtems_counter_ticks_to_nanoseconds( |
---|
61 | stats->total_thread_dispatch_disabled_time |
---|
62 | ); |
---|
63 | |
---|
64 | per_cpu_data->interrupt_count = stats->interrupt_count; |
---|
65 | |
---|
66 | per_cpu_data->total_interrupt_time = |
---|
67 | rtems_counter_ticks_to_nanoseconds( |
---|
68 | stats->total_interrupt_time |
---|
69 | ); |
---|
70 | |
---|
71 | (*visitor)(visitor_arg, data); |
---|
72 | } |
---|
73 | #else |
---|
74 | (void) visitor; |
---|
75 | (void) visitor_arg; |
---|
76 | (void) data; |
---|
77 | #endif |
---|
78 | } |
---|
79 | |
---|
80 | #if defined(RTEMS_PROFILING) && defined(RTEMS_SMP) |
---|
81 | RTEMS_STATIC_ASSERT( |
---|
82 | RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS |
---|
83 | == SMP_LOCK_STATS_CONTENTION_COUNTS, |
---|
84 | smp_lock_contention_counts |
---|
85 | ); |
---|
86 | #endif |
---|
87 | |
---|
88 | static void smp_lock_stats_iterate( |
---|
89 | rtems_profiling_visitor visitor, |
---|
90 | void *visitor_arg, |
---|
91 | rtems_profiling_data *data |
---|
92 | ) |
---|
93 | { |
---|
94 | #if defined(RTEMS_PROFILING) && defined(RTEMS_SMP) |
---|
95 | SMP_lock_Stats_iteration_context iteration_context; |
---|
96 | SMP_lock_Stats snapshot; |
---|
97 | char name[64]; |
---|
98 | |
---|
99 | memset(data, 0, sizeof(*data)); |
---|
100 | data->header.type = RTEMS_PROFILING_SMP_LOCK; |
---|
101 | |
---|
102 | _SMP_lock_Stats_iteration_start(&iteration_context); |
---|
103 | while ( |
---|
104 | _SMP_lock_Stats_iteration_next( |
---|
105 | &iteration_context, |
---|
106 | &snapshot, |
---|
107 | &name[0], |
---|
108 | sizeof(name) |
---|
109 | ) |
---|
110 | ) { |
---|
111 | rtems_profiling_smp_lock *smp_lock_data = &data->smp_lock; |
---|
112 | |
---|
113 | smp_lock_data->name = name; |
---|
114 | smp_lock_data->max_acquire_time = |
---|
115 | rtems_counter_ticks_to_nanoseconds(snapshot.max_acquire_time); |
---|
116 | smp_lock_data->max_section_time = |
---|
117 | rtems_counter_ticks_to_nanoseconds(snapshot.max_section_time); |
---|
118 | smp_lock_data->usage_count = snapshot.usage_count; |
---|
119 | smp_lock_data->total_acquire_time = |
---|
120 | rtems_counter_ticks_to_nanoseconds(snapshot.total_acquire_time); |
---|
121 | smp_lock_data->total_section_time = |
---|
122 | rtems_counter_ticks_to_nanoseconds(snapshot.total_section_time); |
---|
123 | |
---|
124 | memcpy( |
---|
125 | &smp_lock_data->contention_counts[0], |
---|
126 | &snapshot.contention_counts[0], |
---|
127 | sizeof(smp_lock_data->contention_counts) |
---|
128 | ); |
---|
129 | |
---|
130 | (*visitor)(visitor_arg, data); |
---|
131 | } |
---|
132 | _SMP_lock_Stats_iteration_stop(&iteration_context); |
---|
133 | #else |
---|
134 | (void) visitor; |
---|
135 | (void) visitor_arg; |
---|
136 | (void) data; |
---|
137 | #endif |
---|
138 | } |
---|
139 | |
---|
140 | void rtems_profiling_iterate( |
---|
141 | rtems_profiling_visitor visitor, |
---|
142 | void *visitor_arg |
---|
143 | ) |
---|
144 | { |
---|
145 | rtems_profiling_data data; |
---|
146 | |
---|
147 | per_cpu_stats_iterate(visitor, visitor_arg, &data); |
---|
148 | smp_lock_stats_iterate(visitor, visitor_arg, &data); |
---|
149 | } |
---|