source: rtems/cpukit/include/rtems/profiling.h

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

  • Property mode set to 100644
File size: 10.1 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSAPIProfiling
7 *
8 * @brief This header file provides the Profiling Support API.
9 */
10
11/*
12 * Copyright (c) 2014 embedded brains GmbH & Co. KG
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#ifndef _RTEMS_PROFILING_H
37#define _RTEMS_PROFILING_H
38
39#include <stdint.h>
40
41#include <rtems/print.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif /* __cplusplus */
46
47/**
48 * @defgroup RTEMSAPIProfiling Profiling Support
49 *
50 * @ingroup RTEMSAPI
51 *
52 * @brief The profiling support offers functions to report profiling
53 * information available in the system.
54 *
55 * Profiling support is by default disabled.  It must be enabled via the
56 * configure command line with the <tt>--enable-profiling</tt> option.  In this
57 * case the RTEMS_PROFILING pre-processor symbol is defined and profiling
58 * statistics will be gathered during system run-time.  The profiling support
59 * increases the time of critical sections and has some memory overhead.  The
60 * overhead should be acceptable for most applications.  The aim of the
61 * profiling implementation is to be available even for production systems so
62 * that verification is simplified.
63 *
64 * Profiling information includes critical timing values such as the maximum
65 * time of disabled thread dispatching which is a measure for the thread
66 * dispatch latency.  On SMP configurations statistics of all SMP locks in the
67 * system are available.
68 *
69 * Profiling information can be retrieved via rtems_profiling_iterate() and
70 * reported as an XML dump via rtems_profiling_report_xml().  These functions
71 * are always available, but actual profiling data is only available if enabled
72 * at build configuration time.
73 *
74 * @{
75 */
76
77/**
78 * @brief Type of profiling data.
79 */
80typedef enum {
81  /**
82   * @brief Type of per-CPU profiling data.
83   *
84   * @see rtems_profiling_per_cpu.
85   */
86  RTEMS_PROFILING_PER_CPU,
87
88  /**
89   * @brief Type of SMP lock profiling data.
90   *
91   * @see rtems_profiling_smp_lock.
92   */
93  RTEMS_PROFILING_SMP_LOCK
94} rtems_profiling_type;
95
96/**
97 * @brief The profiling data header.
98 */
99typedef struct {
100  /**
101   * @brief The profiling data type.
102   */
103  rtems_profiling_type type;
104} rtems_profiling_header;
105
106/**
107 * @brief Per-CPU profiling data.
108 *
109 * Theoretically all values in this structure can overflow, but the integer
110 * types are chosen so that they cannot overflow in practice.  On systems with
111 * a 1GHz CPU counter, the 64-bit integers can overflow in about 58 years.
112 * Since the system should not spend most of the time in critical sections the
113 * actual system run-time is much longer.  Several other counters in the system
114 * will overflow before we get a problem in the profiling area.
115 */
116typedef struct {
117  /**
118   * @brief The profiling data header.
119   */
120  rtems_profiling_header header;
121
122  /**
123   * @brief The processor index of this profiling data.
124   */
125  uint32_t processor_index;
126
127  /**
128   * @brief The maximum time of disabled thread dispatching in nanoseconds.
129   */
130  uint32_t max_thread_dispatch_disabled_time;
131
132  /**
133   * @brief Count of times when the thread dispatch disable level changes from
134   * zero to one in thread context.
135   *
136   * This value may overflow.
137   */
138  uint64_t thread_dispatch_disabled_count;
139
140  /**
141   * @brief Total time of disabled thread dispatching in nanoseconds.
142   *
143   * The average time of disabled thread dispatching is the total time of
144   * disabled thread dispatching divided by the thread dispatch disabled
145   * count.
146   *
147   * This value may overflow.
148   */
149  uint64_t total_thread_dispatch_disabled_time;
150
151  /**
152   * @brief The maximum interrupt delay in nanoseconds if supported by the
153   * hardware.
154   *
155   * The interrupt delay is the time interval from the recognition of an
156   * interrupt signal by the hardware up to the execution start of the
157   * corresponding high-level handler.  The interrupt delay is the main
158   * contributor to the interrupt latency.  To measure this time hardware
159   * support is required.  A time stamp unit must capture the interrupt signal
160   * recognition time.  If no hardware support is available, then this field
161   * will have a constant value of zero.
162   */
163  uint32_t max_interrupt_delay;
164
165  /**
166   * @brief The maximum time spent to process a single sequence of nested
167   * interrupts in nanoseconds.
168   *
169   * This is the time interval between the change of the interrupt nest level
170   * from zero to one and the change back from one to zero.  It is the measured
171   * worst-case execution time of interrupt service routines.  Please note that
172   * in case of nested interrupts this time includes the combined execution
173   * time and not the maximum time of an individual interrupt service routine.
174   */
175  uint32_t max_interrupt_time;
176
177  /**
178   * @brief Count of times when the interrupt nest level changes from zero to
179   * one.
180   *
181   * This value may overflow.
182   */
183  uint64_t interrupt_count;
184
185  /**
186   * @brief Total time of interrupt processing in nanoseconds.
187   *
188   * The average time of interrupt processing is the total time of interrupt
189   * processing divided by the interrupt count.
190   *
191   * This value may overflow.
192   */
193  uint64_t total_interrupt_time;
194} rtems_profiling_per_cpu;
195
196/**
197 * @brief Count of lock contention counters for SMP lock profiling.
198 */
199#define RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS 4
200
201/**
202 * @brief SMP lock profiling data.
203 *
204 * The lock acquire attempt instant is the point in time right after the
205 * interrupt disable action in the lock acquire sequence.
206 *
207 * The lock acquire instant is the point in time right after the lock
208 * acquisition.  This is the begin of the critical section code execution.
209 *
210 * The lock acquire time is the time elapsed between the lock acquire attempt
211 * instant and the lock acquire instant.
212 *
213 * The lock release instant is the point in time right before the interrupt
214 * enable action in the lock release sequence.
215 *
216 * The lock section time is the time elapsed between the lock acquire instant
217 * and the lock release instant.
218 */
219typedef struct {
220  /**
221   * @brief The profiling data header.
222   */
223  rtems_profiling_header header;
224
225  /**
226   * @brief The lock name.
227   */
228  const char *name;
229
230  /**
231   * @brief The maximum lock acquire time in nanoseconds.
232   */
233  uint32_t max_acquire_time;
234
235  /**
236   * @brief The maximum lock section time in nanoseconds.
237   */
238  uint32_t max_section_time;
239
240  /**
241   * @brief The count of lock uses.
242   *
243   * This value may overflow.
244   */
245  uint64_t usage_count;
246
247  /**
248   * @brief Total lock acquire time in nanoseconds.
249   *
250   * The average lock acquire time is the total acquire time divided by the
251   * lock usage count.  The ration of the total section and total acquire times
252   * gives a measure for the lock contention.
253   *
254   * This value may overflow.
255   */
256  uint64_t total_acquire_time;
257
258  /**
259   * @brief Total lock section time in nanoseconds.
260   *
261   * The average lock section time is the total section time divided by the
262   * lock usage count.
263   *
264   * This value may overflow.
265   */
266  uint64_t total_section_time;
267
268  /**
269   * @brief The counts of lock acquire operations by contention.
270   *
271   * The contention count for index N corresponds to a lock acquire attempt
272   * with an initial queue length of N.  The last index corresponds to all
273   * lock acquire attempts with an initial queue length greater than or equal
274   * to RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS minus one.
275   *
276   * The values may overflow.
277   */
278  uint64_t contention_counts[RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS];
279} rtems_profiling_smp_lock;
280
281/**
282 * @brief Collection of profiling data.
283 */
284typedef union {
285  /**
286   * @brief Header to specify the actual profiling data.
287   */
288  rtems_profiling_header header;
289
290  /**
291   * @brief Per-CPU profiling data if indicated by the header.
292   */
293  rtems_profiling_per_cpu per_cpu;
294
295  /**
296   * @brief SMP lock profiling data if indicated by the header.
297   */
298  rtems_profiling_smp_lock smp_lock;
299} rtems_profiling_data;
300
301/**
302 * @brief Visitor function for the profiling iteration.
303 *
304 * @param[in, out] arg The visitor argument.
305 * @param[in] data The current profiling data.
306 *
307 * @see rtems_profiling_iterate().
308 */
309typedef void (*rtems_profiling_visitor)(
310  void *arg,
311  const rtems_profiling_data *data
312);
313
314/**
315 * @brief Iterates through all profiling data of the system.
316 *
317 * @param[in] visitor The visitor.
318 * @param[in, out] visitor_arg The visitor argument.
319 */
320void rtems_profiling_iterate(
321  rtems_profiling_visitor visitor,
322  void *visitor_arg
323);
324
325/**
326 * @brief Reports profiling data as XML.
327 *
328 * @param[in] name The name of the profiling report.
329 * @param[in] printer The RTEMS printer to send the output too.
330 * @param[in] indentation_level The current indentation level.
331 * @param[in] indentation The string used for indentation.
332 *
333 * @returns As specified by printf().
334 */
335int rtems_profiling_report_xml(
336  const char *name,
337  const rtems_printer *printer,
338  uint32_t indentation_level,
339  const char *indentation
340);
341
342/** @} */
343
344#ifdef __cplusplus
345}
346#endif /* __cplusplus */
347
348#endif /* _RTEMS_PROFILING_H */
Note: See TracBrowser for help on using the repository browser.