![]() |
|
|||
File indexing completed on 2025-05-11 08:24:13
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSScoreSMPLock 0007 * 0008 * @brief This header file provides the interfaces of the 0009 * @ref RTEMSScoreSMPLock related to lock statistics. 0010 */ 0011 0012 /* 0013 * Copyright (C) 2013, 2018 embedded brains GmbH & Co. KG 0014 * 0015 * Redistribution and use in source and binary forms, with or without 0016 * modification, are permitted provided that the following conditions 0017 * are met: 0018 * 1. Redistributions of source code must retain the above copyright 0019 * notice, this list of conditions and the following disclaimer. 0020 * 2. Redistributions in binary form must reproduce the above copyright 0021 * notice, this list of conditions and the following disclaimer in the 0022 * documentation and/or other materials provided with the distribution. 0023 * 0024 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0025 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0026 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0027 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0028 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0029 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0030 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0031 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0032 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0033 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0034 * POSSIBILITY OF SUCH DAMAGE. 0035 */ 0036 0037 #ifndef _RTEMS_SCORE_SMPLOCKSTATS_H 0038 #define _RTEMS_SCORE_SMPLOCKSTATS_H 0039 0040 #include <rtems/score/cpu.h> 0041 0042 #if defined(RTEMS_SMP) 0043 0044 #include <rtems/score/chain.h> 0045 0046 #ifdef __cplusplus 0047 extern "C" { 0048 #endif /* __cplusplus */ 0049 0050 /** 0051 * @addtogroup RTEMSScoreSMPLock 0052 * 0053 * @{ 0054 */ 0055 0056 #if defined(RTEMS_PROFILING) 0057 0058 /** 0059 * @brief Count of lock contention counters for lock statistics. 0060 */ 0061 #define SMP_LOCK_STATS_CONTENTION_COUNTS 4 0062 0063 /** 0064 * @brief SMP lock statistics. 0065 * 0066 * The lock acquire attempt instant is the point in time right after the 0067 * interrupt disable action in the lock acquire sequence. 0068 * 0069 * The lock acquire instant is the point in time right after the lock 0070 * acquisition. This is the begin of the critical section code execution. 0071 * 0072 * The lock release instant is the point in time right before the interrupt 0073 * enable action in the lock release sequence. 0074 * 0075 * The lock section time is the time elapsed between the lock acquire instant 0076 * and the lock release instant. 0077 * 0078 * The lock acquire time is the time elapsed between the lock acquire attempt 0079 * instant and the lock acquire instant. 0080 */ 0081 typedef struct { 0082 /** 0083 * @brief Node for SMP lock statistics chain. 0084 */ 0085 Chain_Node Node; 0086 0087 /** 0088 * @brief The maximum lock acquire time in CPU counter ticks. 0089 */ 0090 CPU_Counter_ticks max_acquire_time; 0091 0092 /** 0093 * @brief The maximum lock section time in CPU counter ticks. 0094 */ 0095 CPU_Counter_ticks max_section_time; 0096 0097 /** 0098 * @brief The count of lock uses. 0099 * 0100 * This value may overflow. 0101 */ 0102 uint64_t usage_count; 0103 0104 /** 0105 * @brief Total lock acquire time in nanoseconds. 0106 * 0107 * The average lock acquire time is the total acquire time divided by the 0108 * lock usage count. The ration of the total section and total acquire times 0109 * gives a measure for the lock contention. 0110 * 0111 * This value may overflow. 0112 */ 0113 uint64_t total_acquire_time; 0114 0115 /** 0116 * @brief The counts of lock acquire operations by contention. 0117 * 0118 * The contention count for index N corresponds to a lock acquire attempt 0119 * with an initial queue length of N. The last index corresponds to all 0120 * lock acquire attempts with an initial queue length greater than or equal 0121 * to SMP_LOCK_STATS_CONTENTION_COUNTS minus one. 0122 * 0123 * The values may overflow. 0124 */ 0125 uint64_t contention_counts[SMP_LOCK_STATS_CONTENTION_COUNTS]; 0126 0127 /** 0128 * @brief Total lock section time in CPU counter ticks. 0129 * 0130 * The average lock section time is the total section time divided by the 0131 * lock usage count. 0132 * 0133 * This value may overflow. 0134 */ 0135 uint64_t total_section_time; 0136 0137 /** 0138 * @brief The lock name. 0139 */ 0140 const char *name; 0141 } SMP_lock_Stats; 0142 0143 /** 0144 * @brief Local context for SMP lock statistics. 0145 */ 0146 typedef struct { 0147 /** 0148 * @brief The last lock acquire instant in CPU counter ticks. 0149 * 0150 * This value is used to measure the lock section time. 0151 */ 0152 CPU_Counter_ticks acquire_instant; 0153 0154 /** 0155 * @brief The lock stats used for the last lock acquire. 0156 */ 0157 SMP_lock_Stats *stats; 0158 } SMP_lock_Stats_context; 0159 0160 /** 0161 * @brief SMP lock statistics initializer for static initialization. 0162 */ 0163 #define SMP_LOCK_STATS_INITIALIZER( name ) \ 0164 { { NULL, NULL }, 0, 0, 0, 0, { 0, 0, 0, 0 }, 0, name } 0165 0166 /** 0167 * @brief Initializes an SMP lock statistics block. 0168 * 0169 * @param[in, out] stats The SMP lock statistics block. 0170 * @param name The name for the SMP lock statistics. This name must be 0171 * persistent throughout the life time of this statistics block. 0172 */ 0173 static inline void _SMP_lock_Stats_initialize( 0174 SMP_lock_Stats *stats, 0175 const char *name 0176 ) 0177 { 0178 SMP_lock_Stats init = SMP_LOCK_STATS_INITIALIZER( name ); 0179 0180 *stats = init; 0181 } 0182 0183 /** 0184 * @brief Destroys an SMP lock statistics block. 0185 * 0186 * @param[out] stats The SMP lock statistics block. 0187 */ 0188 void _SMP_lock_Stats_destroy( SMP_lock_Stats *stats ); 0189 0190 /** 0191 * @brief Sets the max section time of the SMP lock statistics block and 0192 * registers it. 0193 * 0194 * @param[in, out] stats The SMP lock statistics block. 0195 * @param max_section_time The max section time for @a stats. 0196 */ 0197 void _SMP_lock_Stats_register_or_max_section_time( 0198 SMP_lock_Stats *stats, 0199 CPU_Counter_ticks max_section_time 0200 ); 0201 0202 typedef struct { 0203 CPU_Counter_ticks first; 0204 } SMP_lock_Stats_acquire_context; 0205 0206 /** 0207 * @brief Starts the lock stats for acquire. 0208 * 0209 * @param[in, out] acquire_context The acquire context. 0210 */ 0211 static inline void _SMP_lock_Stats_acquire_begin( 0212 SMP_lock_Stats_acquire_context *acquire_context 0213 ) 0214 { 0215 acquire_context->first = _CPU_Counter_read(); 0216 } 0217 0218 /** 0219 * @brief Ends the lock stats for acquire. 0220 * 0221 * @param acquire_context The acquire context for the operation. 0222 * @param[in, out] stats The stats to modify. 0223 * @param[out] stats_context The context for the stats. 0224 * @param queue_length The queue length for the stats contention counts. 0225 */ 0226 static inline void _SMP_lock_Stats_acquire_end( 0227 const SMP_lock_Stats_acquire_context *acquire_context, 0228 SMP_lock_Stats *stats, 0229 SMP_lock_Stats_context *stats_context, 0230 unsigned int queue_length 0231 ) 0232 { 0233 CPU_Counter_ticks second; 0234 CPU_Counter_ticks delta; 0235 0236 second = _CPU_Counter_read(); 0237 stats_context->acquire_instant = second; 0238 delta = second - acquire_context->first; 0239 0240 ++stats->usage_count; 0241 0242 stats->total_acquire_time += delta; 0243 0244 if ( stats->max_acquire_time < delta ) { 0245 stats->max_acquire_time = delta; 0246 } 0247 0248 if ( queue_length >= SMP_LOCK_STATS_CONTENTION_COUNTS ) { 0249 queue_length = SMP_LOCK_STATS_CONTENTION_COUNTS - 1; 0250 } 0251 ++stats->contention_counts[ queue_length ]; 0252 0253 stats_context->stats = stats; 0254 } 0255 0256 /** 0257 * @brief Updates an SMP lock statistics block during a lock release. 0258 * 0259 * @param[in, out] stats_context The SMP lock statistics context. 0260 */ 0261 static inline void _SMP_lock_Stats_release_update( 0262 const SMP_lock_Stats_context *stats_context 0263 ) 0264 { 0265 SMP_lock_Stats *stats; 0266 CPU_Counter_ticks first; 0267 CPU_Counter_ticks second; 0268 CPU_Counter_ticks delta; 0269 0270 stats = stats_context->stats; 0271 first = stats_context->acquire_instant; 0272 second = _CPU_Counter_read(); 0273 delta = second - first; 0274 0275 stats->total_section_time += delta; 0276 0277 if ( stats->max_section_time < delta ) { 0278 _SMP_lock_Stats_register_or_max_section_time( stats, delta ); 0279 } 0280 } 0281 0282 typedef struct { 0283 Chain_Node Node; 0284 SMP_lock_Stats *current; 0285 } SMP_lock_Stats_iteration_context; 0286 0287 /** 0288 * @brief Adds a newly initialized node to the iteration context. 0289 * 0290 * @param[in, out] iteration_context The iteration context for the operation. 0291 */ 0292 void _SMP_lock_Stats_iteration_start( 0293 SMP_lock_Stats_iteration_context *iteration_context 0294 ); 0295 0296 /** 0297 * @brief Gets the next statistics node, if it is valid. 0298 * 0299 * @param[in, out] iteration_context The iteration context. 0300 * @param[out] snapshot Contains the next node of the stats chain. 0301 * @param[in, out] name The name for @a snapshot. 0302 * @param name_size The size of @a name. 0303 * 0304 * @retval true The node is valid. 0305 * @retval false The node is not valid. 0306 */ 0307 bool _SMP_lock_Stats_iteration_next( 0308 SMP_lock_Stats_iteration_context *iteration_context, 0309 SMP_lock_Stats *snapshot, 0310 char *name, 0311 size_t name_size 0312 ); 0313 0314 /** 0315 * @brief Removes a node from the iteration context. 0316 * 0317 * @param[in, out] iteration_context The iteration context for the operation. 0318 */ 0319 void _SMP_lock_Stats_iteration_stop( 0320 SMP_lock_Stats_iteration_context *iteration_context 0321 ); 0322 0323 #else /* RTEMS_PROFILING */ 0324 0325 #define _SMP_lock_Stats_initialize( stats, name ) do { } while ( 0 ) 0326 0327 #define _SMP_lock_Stats_destroy( stats ) do { } while ( 0 ) 0328 0329 #endif /* !RTEMS_PROFILING */ 0330 0331 /** @} */ 0332 0333 #ifdef __cplusplus 0334 } 0335 #endif /* __cplusplus */ 0336 0337 #endif /* RTEMS_SMP */ 0338 0339 #endif /* _RTEMS_SCORE_SMPLOCKSTATS_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |