Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSAPIProfiling
0007  *
0008  * @brief This header file provides the Profiling Support API.
0009  */
0010 
0011 /*
0012  * Copyright (c) 2014 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifndef _RTEMS_PROFILING_H
0037 #define _RTEMS_PROFILING_H
0038 
0039 #include <stdint.h>
0040 
0041 #include <rtems/print.h>
0042 
0043 #ifdef __cplusplus
0044 extern "C" {
0045 #endif /* __cplusplus */
0046 
0047 /**
0048  * @defgroup RTEMSAPIProfiling Profiling Support
0049  *
0050  * @ingroup RTEMSAPI
0051  *
0052  * @brief The profiling support offers functions to report profiling
0053  * information available in the system.
0054  *
0055  * Profiling support is by default disabled.  It must be enabled via the
0056  * configure command line with the <tt>--enable-profiling</tt> option.  In this
0057  * case the RTEMS_PROFILING pre-processor symbol is defined and profiling
0058  * statistics will be gathered during system run-time.  The profiling support
0059  * increases the time of critical sections and has some memory overhead.  The
0060  * overhead should be acceptable for most applications.  The aim of the
0061  * profiling implementation is to be available even for production systems so
0062  * that verification is simplified.
0063  *
0064  * Profiling information includes critical timing values such as the maximum
0065  * time of disabled thread dispatching which is a measure for the thread
0066  * dispatch latency.  On SMP configurations statistics of all SMP locks in the
0067  * system are available.
0068  *
0069  * Profiling information can be retrieved via rtems_profiling_iterate() and
0070  * reported as an XML dump via rtems_profiling_report_xml().  These functions
0071  * are always available, but actual profiling data is only available if enabled
0072  * at build configuration time.
0073  *
0074  * @{
0075  */
0076 
0077 /**
0078  * @brief Type of profiling data.
0079  */
0080 typedef enum {
0081   /**
0082    * @brief Type of per-CPU profiling data.
0083    *
0084    * @see rtems_profiling_per_cpu.
0085    */
0086   RTEMS_PROFILING_PER_CPU,
0087 
0088   /**
0089    * @brief Type of SMP lock profiling data.
0090    *
0091    * @see rtems_profiling_smp_lock.
0092    */
0093   RTEMS_PROFILING_SMP_LOCK
0094 } rtems_profiling_type;
0095 
0096 /**
0097  * @brief The profiling data header.
0098  */
0099 typedef struct {
0100   /**
0101    * @brief The profiling data type.
0102    */
0103   rtems_profiling_type type;
0104 } rtems_profiling_header;
0105 
0106 /**
0107  * @brief Per-CPU profiling data.
0108  *
0109  * Theoretically all values in this structure can overflow, but the integer
0110  * types are chosen so that they cannot overflow in practice.  On systems with
0111  * a 1GHz CPU counter, the 64-bit integers can overflow in about 58 years.
0112  * Since the system should not spend most of the time in critical sections the
0113  * actual system run-time is much longer.  Several other counters in the system
0114  * will overflow before we get a problem in the profiling area.
0115  */
0116 typedef struct {
0117   /**
0118    * @brief The profiling data header.
0119    */
0120   rtems_profiling_header header;
0121 
0122   /**
0123    * @brief The processor index of this profiling data.
0124    */
0125   uint32_t processor_index;
0126 
0127   /**
0128    * @brief The maximum time of disabled thread dispatching in nanoseconds.
0129    */
0130   uint32_t max_thread_dispatch_disabled_time;
0131 
0132   /**
0133    * @brief Count of times when the thread dispatch disable level changes from
0134    * zero to one in thread context.
0135    *
0136    * This value may overflow.
0137    */
0138   uint64_t thread_dispatch_disabled_count;
0139 
0140   /**
0141    * @brief Total time of disabled thread dispatching in nanoseconds.
0142    *
0143    * The average time of disabled thread dispatching is the total time of
0144    * disabled thread dispatching divided by the thread dispatch disabled
0145    * count.
0146    *
0147    * This value may overflow.
0148    */
0149   uint64_t total_thread_dispatch_disabled_time;
0150 
0151   /**
0152    * @brief The maximum interrupt delay in nanoseconds if supported by the
0153    * hardware.
0154    *
0155    * The interrupt delay is the time interval from the recognition of an
0156    * interrupt signal by the hardware up to the execution start of the
0157    * corresponding high-level handler.  The interrupt delay is the main
0158    * contributor to the interrupt latency.  To measure this time hardware
0159    * support is required.  A time stamp unit must capture the interrupt signal
0160    * recognition time.  If no hardware support is available, then this field
0161    * will have a constant value of zero.
0162    */
0163   uint32_t max_interrupt_delay;
0164 
0165   /**
0166    * @brief The maximum time spent to process a single sequence of nested
0167    * interrupts in nanoseconds.
0168    *
0169    * This is the time interval between the change of the interrupt nest level
0170    * from zero to one and the change back from one to zero.  It is the measured
0171    * worst-case execution time of interrupt service routines.  Please note that
0172    * in case of nested interrupts this time includes the combined execution
0173    * time and not the maximum time of an individual interrupt service routine.
0174    */
0175   uint32_t max_interrupt_time;
0176 
0177   /**
0178    * @brief Count of times when the interrupt nest level changes from zero to
0179    * one.
0180    *
0181    * This value may overflow.
0182    */
0183   uint64_t interrupt_count;
0184 
0185   /**
0186    * @brief Total time of interrupt processing in nanoseconds.
0187    *
0188    * The average time of interrupt processing is the total time of interrupt
0189    * processing divided by the interrupt count.
0190    *
0191    * This value may overflow.
0192    */
0193   uint64_t total_interrupt_time;
0194 } rtems_profiling_per_cpu;
0195 
0196 /**
0197  * @brief Count of lock contention counters for SMP lock profiling.
0198  */
0199 #define RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS 4
0200 
0201 /**
0202  * @brief SMP lock profiling data.
0203  *
0204  * The lock acquire attempt instant is the point in time right after the
0205  * interrupt disable action in the lock acquire sequence.
0206  *
0207  * The lock acquire instant is the point in time right after the lock
0208  * acquisition.  This is the begin of the critical section code execution.
0209  *
0210  * The lock acquire time is the time elapsed between the lock acquire attempt
0211  * instant and the lock acquire instant.
0212  *
0213  * The lock release instant is the point in time right before the interrupt
0214  * enable action in the lock release sequence.
0215  *
0216  * The lock section time is the time elapsed between the lock acquire instant
0217  * and the lock release instant.
0218  */
0219 typedef struct {
0220   /**
0221    * @brief The profiling data header.
0222    */
0223   rtems_profiling_header header;
0224 
0225   /**
0226    * @brief The lock name.
0227    */
0228   const char *name;
0229 
0230   /**
0231    * @brief The maximum lock acquire time in nanoseconds.
0232    */
0233   uint32_t max_acquire_time;
0234 
0235   /**
0236    * @brief The maximum lock section time in nanoseconds.
0237    */
0238   uint32_t max_section_time;
0239 
0240   /**
0241    * @brief The count of lock uses.
0242    *
0243    * This value may overflow.
0244    */
0245   uint64_t usage_count;
0246 
0247   /**
0248    * @brief Total lock acquire time in nanoseconds.
0249    *
0250    * The average lock acquire time is the total acquire time divided by the
0251    * lock usage count.  The ration of the total section and total acquire times
0252    * gives a measure for the lock contention.
0253    *
0254    * This value may overflow.
0255    */
0256   uint64_t total_acquire_time;
0257 
0258   /**
0259    * @brief Total lock section time in nanoseconds.
0260    *
0261    * The average lock section time is the total section time divided by the
0262    * lock usage count.
0263    *
0264    * This value may overflow.
0265    */
0266   uint64_t total_section_time;
0267 
0268   /**
0269    * @brief The counts of lock acquire operations by contention.
0270    *
0271    * The contention count for index N corresponds to a lock acquire attempt
0272    * with an initial queue length of N.  The last index corresponds to all
0273    * lock acquire attempts with an initial queue length greater than or equal
0274    * to RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS minus one.
0275    *
0276    * The values may overflow.
0277    */
0278   uint64_t contention_counts[RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS];
0279 } rtems_profiling_smp_lock;
0280 
0281 /**
0282  * @brief Collection of profiling data.
0283  */
0284 typedef union {
0285   /**
0286    * @brief Header to specify the actual profiling data.
0287    */
0288   rtems_profiling_header header;
0289 
0290   /**
0291    * @brief Per-CPU profiling data if indicated by the header.
0292    */
0293   rtems_profiling_per_cpu per_cpu;
0294 
0295   /**
0296    * @brief SMP lock profiling data if indicated by the header.
0297    */
0298   rtems_profiling_smp_lock smp_lock;
0299 } rtems_profiling_data;
0300 
0301 /**
0302  * @brief Visitor function for the profiling iteration.
0303  *
0304  * @param[in, out] arg The visitor argument.
0305  * @param[in] data The current profiling data.
0306  *
0307  * @see rtems_profiling_iterate().
0308  */
0309 typedef void (*rtems_profiling_visitor)(
0310   void *arg,
0311   const rtems_profiling_data *data
0312 );
0313 
0314 /**
0315  * @brief Iterates through all profiling data of the system.
0316  *
0317  * @param[in] visitor The visitor.
0318  * @param[in, out] visitor_arg The visitor argument.
0319  */
0320 void rtems_profiling_iterate(
0321   rtems_profiling_visitor visitor,
0322   void *visitor_arg
0323 );
0324 
0325 /**
0326  * @brief Reports profiling data as XML.
0327  *
0328  * @param[in] name The name of the profiling report.
0329  * @param[in] printer The RTEMS printer to send the output too.
0330  * @param[in] indentation_level The current indentation level.
0331  * @param[in] indentation The string used for indentation.
0332  *
0333  * @returns As specified by printf().
0334  */
0335 int rtems_profiling_report_xml(
0336   const char *name,
0337   const rtems_printer *printer,
0338   uint32_t indentation_level,
0339   const char *indentation
0340 );
0341 
0342 /** @} */
0343 
0344 #ifdef __cplusplus
0345 }
0346 #endif /* __cplusplus */
0347 
0348 #endif /* _RTEMS_PROFILING_H */