source: rtems/cpukit/sapi/src/profilingreportxml.c @ 599d71f

Last change on this file since 599d71f was 8365ad1, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 22, 2014 at 9:46:10 AM

sapi: Add arithmetic means to XML profiling report

  • Property mode set to 100644
File size: 7.0 KB
Line 
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
21#ifdef RTEMS_PROFILING
22
23#include <inttypes.h>
24
25typedef struct {
26  rtems_profiling_printf printf_func;
27  void *printf_arg;
28  uint32_t indentation_level;
29  const char *indentation;
30  int retval;
31} context;
32
33static void update_retval(context *ctx, int rv)
34{
35  if (rv > 0 && ctx->retval >= 0) {
36    ctx->retval += rv;
37  }
38}
39
40static void indent(context *ctx, uint32_t indentation_level)
41{
42  uint32_t n = ctx->indentation_level + indentation_level;
43  uint32_t i;
44
45  for (i = 0; i < n; ++i) {
46    int rv = (*ctx->printf_func)(ctx->printf_arg, "%s", ctx->indentation);
47
48    update_retval(ctx, rv);
49  }
50}
51
52static uint64_t arithmetic_mean(uint64_t total, uint64_t count)
53{
54  return count != 0 ? total / count : 0;
55}
56
57static void report_per_cpu(context *ctx, const rtems_profiling_per_cpu *per_cpu)
58{
59  rtems_profiling_printf printf_func = ctx->printf_func;
60  void *printf_arg = ctx->printf_arg;
61  int rv;
62
63  indent(ctx, 1);
64  rv = (*printf_func)(
65    printf_arg,
66    "<PerCPUProfilingReport processorIndex=\"%" PRIu32 "\">\n",
67    per_cpu->processor_index
68  );
69  update_retval(ctx, rv);
70
71  indent(ctx, 2);
72  rv = (*printf_func)(
73    printf_arg,
74    "<MaxThreadDispatchDisabledTime unit=\"ns\">%" PRIu32
75      "</MaxThreadDispatchDisabledTime>\n",
76    per_cpu->max_thread_dispatch_disabled_time
77  );
78  update_retval(ctx, rv);
79
80  indent(ctx, 2);
81  rv = (*printf_func)(
82    printf_arg,
83    "<MeanThreadDispatchDisabledTime unit=\"ns\">%" PRIu64
84      "</MeanThreadDispatchDisabledTime>\n",
85    arithmetic_mean(
86      per_cpu->total_thread_dispatch_disabled_time,
87      per_cpu->thread_dispatch_disabled_count
88    )
89  );
90  update_retval(ctx, rv);
91
92  indent(ctx, 2);
93  rv = (*printf_func)(
94    printf_arg,
95    "<TotalThreadDispatchDisabledTime unit=\"ns\">%" PRIu64
96      "</TotalThreadDispatchDisabledTime>\n",
97    per_cpu->total_thread_dispatch_disabled_time
98  );
99  update_retval(ctx, rv);
100
101  indent(ctx, 2);
102  rv = (*printf_func)(
103    printf_arg,
104    "<ThreadDispatchDisabledCount>%" PRIu64 "</ThreadDispatchDisabledCount>\n",
105    per_cpu->thread_dispatch_disabled_count
106  );
107  update_retval(ctx, rv);
108
109  indent(ctx, 2);
110  rv = (*printf_func)(
111    printf_arg,
112    "<MaxInterruptDelay unit=\"ns\">%" PRIu32 "</MaxInterruptDelay>\n",
113    per_cpu->max_interrupt_delay
114  );
115  update_retval(ctx, rv);
116
117  indent(ctx, 2);
118  rv = (*printf_func)(
119    printf_arg,
120    "<MaxInterruptTime unit=\"ns\">%" PRIu32
121      "</MaxInterruptTime>\n",
122    per_cpu->max_interrupt_time
123  );
124  update_retval(ctx, rv);
125
126  indent(ctx, 2);
127  rv = (*printf_func)(
128    printf_arg,
129    "<MeanInterruptTime unit=\"ns\">%" PRIu64
130      "</MeanInterruptTime>\n",
131    arithmetic_mean(
132      per_cpu->total_interrupt_time,
133      per_cpu->interrupt_count
134    )
135  );
136  update_retval(ctx, rv);
137
138  indent(ctx, 2);
139  rv = (*printf_func)(
140    printf_arg,
141    "<TotalInterruptTime unit=\"ns\">%" PRIu64 "</TotalInterruptTime>\n",
142    per_cpu->total_interrupt_time
143  );
144  update_retval(ctx, rv);
145
146  indent(ctx, 2);
147  rv = (*printf_func)(
148    printf_arg,
149    "<InterruptCount>%" PRIu64 "</InterruptCount>\n",
150    per_cpu->interrupt_count
151  );
152  update_retval(ctx, rv);
153
154  indent(ctx, 1);
155  rv = (*printf_func)(
156    printf_arg,
157    "</PerCPUProfilingReport>\n"
158  );
159  update_retval(ctx, rv);
160}
161
162static void report_smp_lock(context *ctx, const rtems_profiling_smp_lock *smp_lock)
163{
164  rtems_profiling_printf printf_func = ctx->printf_func;
165  void *printf_arg = ctx->printf_arg;
166  int rv;
167  uint32_t i;
168
169  indent(ctx, 1);
170  rv = (*printf_func)(
171    printf_arg,
172    "<SMPLockProfilingReport name=\"%s\">\n",
173    smp_lock->name
174  );
175  update_retval(ctx, rv);
176
177  indent(ctx, 2);
178  rv = (*printf_func)(
179    printf_arg,
180    "<MaxAcquireTime unit=\"ns\">%" PRIu32 "</MaxAcquireTime>\n",
181    smp_lock->max_acquire_time
182  );
183  update_retval(ctx, rv);
184
185  indent(ctx, 2);
186  rv = (*printf_func)(
187    printf_arg,
188    "<MaxSectionTime unit=\"ns\">%" PRIu32 "</MaxSectionTime>\n",
189    smp_lock->max_section_time
190  );
191  update_retval(ctx, rv);
192
193  indent(ctx, 2);
194  rv = (*printf_func)(
195    printf_arg,
196    "<MeanAcquireTime unit=\"ns\">%" PRIu64
197      "</MeanAcquireTime>\n",
198    arithmetic_mean(
199      smp_lock->total_acquire_time,
200      smp_lock->usage_count
201    )
202  );
203  update_retval(ctx, rv);
204
205  indent(ctx, 2);
206  rv = (*printf_func)(
207    printf_arg,
208    "<MeanSectionTime unit=\"ns\">%" PRIu64
209      "</MeanSectionTime>\n",
210    arithmetic_mean(
211      smp_lock->total_section_time,
212      smp_lock->usage_count
213    )
214  );
215  update_retval(ctx, rv);
216
217  indent(ctx, 2);
218  rv = (*printf_func)(
219    printf_arg,
220    "<TotalAcquireTime unit=\"ns\">%" PRIu64 "</TotalAcquireTime>\n",
221    smp_lock->total_acquire_time
222  );
223  update_retval(ctx, rv);
224
225  indent(ctx, 2);
226  rv = (*printf_func)(
227    printf_arg,
228    "<TotalSectionTime unit=\"ns\">%" PRIu64 "</TotalSectionTime>\n",
229    smp_lock->total_section_time
230  );
231  update_retval(ctx, rv);
232
233  indent(ctx, 2);
234  rv = (*printf_func)(
235    printf_arg,
236    "<UsageCount>%" PRIu64 "</UsageCount>\n",
237    smp_lock->usage_count
238  );
239  update_retval(ctx, rv);
240
241  for (i = 0; i < RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS; ++i) {
242    indent(ctx, 2);
243    rv = (*printf_func)(
244      printf_arg,
245      "<ContentionCount initialQueueLength=\"%" PRIu32 "\">%"
246        PRIu64 "</ContentionCount>\n",
247      i,
248      smp_lock->contention_counts[i]
249    );
250    update_retval(ctx, rv);
251  }
252
253  indent(ctx, 1);
254  rv = (*printf_func)(
255    printf_arg,
256    "</SMPLockProfilingReport>\n"
257  );
258  update_retval(ctx, rv);
259}
260
261static void report(void *arg, const rtems_profiling_data *data)
262{
263  context *ctx = arg;
264
265  switch (data->header.type) {
266    case RTEMS_PROFILING_PER_CPU:
267      report_per_cpu(ctx, &data->per_cpu);
268      break;
269    case RTEMS_PROFILING_SMP_LOCK:
270      report_smp_lock(ctx, &data->smp_lock);
271      break;
272  }
273}
274
275#endif /* RTEMS_PROFILING */
276
277int rtems_profiling_report_xml(
278  const char *name,
279  rtems_profiling_printf printf_func,
280  void *printf_arg,
281  uint32_t indentation_level,
282  const char *indentation
283)
284{
285#ifdef RTEMS_PROFILING
286  context ctx_instance = {
287    .printf_func = printf_func,
288    .printf_arg = printf_arg,
289    .indentation_level = indentation_level,
290    .indentation = indentation,
291    .retval = 0
292  };
293  context *ctx = &ctx_instance;
294  int rv;
295
296  indent(ctx, 0);
297  rv = (*printf_func)(printf_arg, "<ProfilingReport name=\"%s\">\n", name);
298  update_retval(ctx, rv);
299
300  rtems_profiling_iterate(report, ctx);
301
302  indent(ctx, 0);
303  rv = (*printf_func)(printf_arg, "</ProfilingReport>\n");
304  update_retval(ctx, rv);
305
306  return ctx->retval;
307#else /* RTEMS_PROFILING */
308  (void) name;
309  (void) printf_func;
310  (void) printf_arg;
311  (void) indentation_level;
312  (void) indentation;
313
314  return 0;
315#endif /* RTEMS_PROFILING */
316}
Note: See TracBrowser for help on using the repository browser.