1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #ifdef HAVE_CONFIG_H1 |
15 | #include "config.h" |
16 | #endif |
17 | |
18 | #include <rtems.h> |
19 | #include <stdlib.h> |
20 | #include <ctype.h> |
21 | #include <inttypes.h> |
22 | |
23 | #include <rtems/bspIo.h> |
24 | #include <rtems/score/timespec.h> |
25 | |
26 | #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ |
27 | |
28 | #define NANOSECONDS_DIVIDER1000 1000 |
29 | #define PERCENT_FMT"%04" "d" "%04" PRId32"d" |
30 | #define NANOSECONDS_FMT"%06" "d" "%06" PRId32"d" |
31 | #endif |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | void rtems_rate_monotonic_report_statistics_with_plugin( |
42 | void *context, |
43 | rtems_printk_plugin_t print |
44 | ) |
45 | { |
46 | rtems_status_code status; |
47 | rtems_id id; |
48 | rtems_rate_monotonic_period_statistics the_stats; |
49 | rtems_rate_monotonic_period_status the_status; |
50 | char name[5]; |
51 | |
52 | if ( !print ) |
53 | return; |
54 | |
55 | (*print)( context, "Period information by period\n" ); |
56 | #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ |
57 | (*print)( context, "--- CPU times are in seconds ---\n" ); |
58 | (*print)( context, "--- Wall times are in seconds ---\n" ); |
59 | #endif |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | (*print)( context, " ID OWNER COUNT MISSED " |
74 | #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ |
75 | " " |
76 | #endif |
77 | "CPU TIME " |
78 | #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ |
79 | " " |
80 | #endif |
81 | " WALL TIME\n" |
82 | ); |
83 | (*print)( context, " " |
84 | #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ |
85 | " " |
86 | #endif |
87 | "MIN/MAX/AVG " |
88 | #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ |
89 | " " |
90 | #endif |
91 | " MIN/MAX/AVG\n" |
92 | ); |
93 | |
94 | |
95 | |
96 | |
97 | |
98 | for ( id=_Rate_monotonic_Information.minimum_id ; |
99 | id <= _Rate_monotonic_Information.maximum_id ; |
100 | id++ ) { |
101 | status = rtems_rate_monotonic_get_statistics( id, &the_stats ); |
102 | if ( status != RTEMS_SUCCESSFUL ) |
103 | continue; |
104 | |
105 | |
106 | status = rtems_rate_monotonic_get_status( id, &the_status ); |
| Value stored to 'status' is never read |
107 | #if defined(RTEMS_DEBUG) |
108 | if ( status != RTEMS_SUCCESSFUL ) |
109 | continue; |
110 | #endif |
111 | |
112 | rtems_object_get_name( the_status.owner, sizeof(name), name ); |
113 | |
114 | |
115 | |
116 | |
117 | (*print)( context, |
118 | "0x%08" PRIx32"x" " %4s %5" PRId32"d" " %6" PRId32"d" " ", |
119 | id, name, |
120 | the_stats.count, the_stats.missed_count |
121 | ); |
122 | |
123 | |
124 | |
125 | |
126 | if (the_stats.count == 0) { |
127 | (*print)( context, "\n" ); |
128 | continue; |
129 | } |
130 | |
131 | |
132 | |
133 | |
134 | { |
135 | #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ |
136 | struct timespec cpu_average; |
137 | struct timespec *min_cpu = &the_stats.min_cpu_time; |
138 | struct timespec *max_cpu = &the_stats.max_cpu_time; |
139 | struct timespec *total_cpu = &the_stats.total_cpu_time; |
140 | |
141 | _Timespec_Divide_by_integer( total_cpu, the_stats.count, &cpu_average ); |
142 | (*print)( context, |
143 | "%" PRId32"d" "." NANOSECONDS_FMT"%06" "d" "/" |
144 | "%" PRId32"d" "." NANOSECONDS_FMT"%06" "d" "/" |
145 | "%" PRId32"d" "." NANOSECONDS_FMT"%06" "d" " ", |
146 | _Timespec_Get_seconds( min_cpu )((min_cpu)->tv_sec), |
147 | _Timespec_Get_nanoseconds( min_cpu )((min_cpu)->tv_nsec) / NANOSECONDS_DIVIDER1000, |
148 | _Timespec_Get_seconds( max_cpu )((max_cpu)->tv_sec), |
149 | _Timespec_Get_nanoseconds( max_cpu )((max_cpu)->tv_nsec) / NANOSECONDS_DIVIDER1000, |
150 | _Timespec_Get_seconds( &cpu_average )((&cpu_average)->tv_sec), |
151 | _Timespec_Get_nanoseconds( &cpu_average )((&cpu_average)->tv_nsec) / NANOSECONDS_DIVIDER1000 |
152 | ); |
153 | #else |
154 | uint32_t ival_cpu, fval_cpu; |
155 | |
156 | ival_cpu = the_stats.total_cpu_time * 100 / the_stats.count; |
157 | fval_cpu = ival_cpu % 100; |
158 | ival_cpu /= 100; |
159 | |
160 | (*print)( context, |
161 | "%3" PRId32"d" "/%4" PRId32"d" "/%3" PRId32"d" ".%02" PRId32"d" " ", |
162 | the_stats.min_cpu_time, the_stats.max_cpu_time, ival_cpu, fval_cpu |
163 | ); |
164 | #endif |
165 | } |
166 | |
167 | |
168 | |
169 | |
170 | { |
171 | #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ |
172 | struct timespec wall_average; |
173 | struct timespec *min_wall = &the_stats.min_wall_time; |
174 | struct timespec *max_wall = &the_stats.max_wall_time; |
175 | struct timespec *total_wall = &the_stats.total_wall_time; |
176 | |
177 | _Timespec_Divide_by_integer(total_wall, the_stats.count, &wall_average); |
178 | (*print)( context, |
179 | "%" PRId32"d" "." NANOSECONDS_FMT"%06" "d" "/" |
180 | "%" PRId32"d" "." NANOSECONDS_FMT"%06" "d" "/" |
181 | "%" PRId32"d" "." NANOSECONDS_FMT"%06" "d" "\n", |
182 | _Timespec_Get_seconds( min_wall )((min_wall)->tv_sec), |
183 | _Timespec_Get_nanoseconds( min_wall )((min_wall)->tv_nsec) / NANOSECONDS_DIVIDER1000, |
184 | _Timespec_Get_seconds( max_wall )((max_wall)->tv_sec), |
185 | _Timespec_Get_nanoseconds( max_wall )((max_wall)->tv_nsec) / NANOSECONDS_DIVIDER1000, |
186 | _Timespec_Get_seconds( &wall_average )((&wall_average)->tv_sec), |
187 | _Timespec_Get_nanoseconds( &wall_average )((&wall_average)->tv_nsec) / NANOSECONDS_DIVIDER1000 |
188 | ); |
189 | #else |
190 | uint32_t ival_wall, fval_wall; |
191 | |
192 | ival_wall = the_stats.total_wall_time * 100 / the_stats.count; |
193 | fval_wall = ival_wall % 100; |
194 | ival_wall /= 100; |
195 | (*print)( context, |
196 | "%3" PRId32"d" "/%4" PRId32"d" "/%3" PRId32"d" ".%02" PRId32"d" "\n", |
197 | the_stats.min_wall_time, the_stats.max_wall_time, ival_wall, fval_wall |
198 | ); |
199 | #endif |
200 | } |
201 | } |
202 | } |
203 | |
204 | void rtems_rate_monotonic_report_statistics( void ) |
205 | { |
206 | rtems_rate_monotonic_report_statistics_with_plugin( NULL((void*)0), printk_plugin ); |
207 | } |