Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSAPIProfiling
0007  *
0008  * @brief This source file contains the implementation of
0009  *   rtems_profiling_iterate().
0010  */
0011 
0012 /*
0013  * Copyright (c) 2014 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 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040 
0041 #include <rtems/profiling.h>
0042 #include <rtems/counter.h>
0043 #include <rtems/score/percpu.h>
0044 #include <rtems/score/smplock.h>
0045 #include <rtems.h>
0046 
0047 #include <string.h>
0048 
0049 static void per_cpu_stats_iterate(
0050   rtems_profiling_visitor visitor,
0051   void *visitor_arg,
0052   rtems_profiling_data *data
0053 )
0054 {
0055 #ifdef RTEMS_PROFILING
0056   uint32_t n = rtems_scheduler_get_processor_maximum();
0057   uint32_t i;
0058 
0059   memset(data, 0, sizeof(*data));
0060   data->header.type = RTEMS_PROFILING_PER_CPU;
0061   for (i = 0; i < n; ++i) {
0062     const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index(i);
0063     const Per_CPU_Stats *stats = &per_cpu->Stats;
0064     rtems_profiling_per_cpu *per_cpu_data = &data->per_cpu;
0065 
0066     per_cpu_data->processor_index = i;
0067 
0068     per_cpu_data->max_thread_dispatch_disabled_time =
0069       rtems_counter_ticks_to_nanoseconds(
0070         stats->max_thread_dispatch_disabled_time
0071       );
0072 
0073     per_cpu_data->max_interrupt_time =
0074       rtems_counter_ticks_to_nanoseconds(stats->max_interrupt_time);
0075 
0076     per_cpu_data->max_interrupt_delay =
0077       rtems_counter_ticks_to_nanoseconds(stats->max_interrupt_delay);
0078 
0079     per_cpu_data->thread_dispatch_disabled_count =
0080       stats->thread_dispatch_disabled_count;
0081 
0082     per_cpu_data->total_thread_dispatch_disabled_time =
0083       rtems_counter_ticks_to_nanoseconds(
0084         stats->total_thread_dispatch_disabled_time
0085       );
0086 
0087     per_cpu_data->interrupt_count = stats->interrupt_count;
0088 
0089     per_cpu_data->total_interrupt_time =
0090       rtems_counter_ticks_to_nanoseconds(
0091         stats->total_interrupt_time
0092       );
0093 
0094     (*visitor)(visitor_arg, data);
0095   }
0096 #else
0097   (void) visitor;
0098   (void) visitor_arg;
0099   (void) data;
0100 #endif
0101 }
0102 
0103 #if defined(RTEMS_PROFILING) && defined(RTEMS_SMP)
0104 RTEMS_STATIC_ASSERT(
0105   RTEMS_PROFILING_SMP_LOCK_CONTENTION_COUNTS
0106     == SMP_LOCK_STATS_CONTENTION_COUNTS,
0107   smp_lock_contention_counts
0108 );
0109 #endif
0110 
0111 static void smp_lock_stats_iterate(
0112   rtems_profiling_visitor visitor,
0113   void *visitor_arg,
0114   rtems_profiling_data *data
0115 )
0116 {
0117 #if defined(RTEMS_PROFILING) && defined(RTEMS_SMP)
0118   SMP_lock_Stats_iteration_context iteration_context;
0119   SMP_lock_Stats snapshot;
0120   char name[64];
0121 
0122   memset(data, 0, sizeof(*data));
0123   data->header.type = RTEMS_PROFILING_SMP_LOCK;
0124 
0125   _SMP_lock_Stats_iteration_start(&iteration_context);
0126   while (
0127     _SMP_lock_Stats_iteration_next(
0128       &iteration_context,
0129       &snapshot,
0130       &name[0],
0131       sizeof(name)
0132     )
0133   ) {
0134     rtems_profiling_smp_lock *smp_lock_data = &data->smp_lock;
0135 
0136     smp_lock_data->name = name;
0137     smp_lock_data->max_acquire_time =
0138       rtems_counter_ticks_to_nanoseconds(snapshot.max_acquire_time);
0139     smp_lock_data->max_section_time =
0140       rtems_counter_ticks_to_nanoseconds(snapshot.max_section_time);
0141     smp_lock_data->usage_count = snapshot.usage_count;
0142     smp_lock_data->total_acquire_time =
0143       rtems_counter_ticks_to_nanoseconds(snapshot.total_acquire_time);
0144     smp_lock_data->total_section_time =
0145       rtems_counter_ticks_to_nanoseconds(snapshot.total_section_time);
0146 
0147     memcpy(
0148       &smp_lock_data->contention_counts[0],
0149       &snapshot.contention_counts[0],
0150       sizeof(smp_lock_data->contention_counts)
0151     );
0152 
0153     (*visitor)(visitor_arg, data);
0154   }
0155   _SMP_lock_Stats_iteration_stop(&iteration_context);
0156 #else
0157   (void) visitor;
0158   (void) visitor_arg;
0159   (void) data;
0160 #endif
0161 }
0162 
0163 void rtems_profiling_iterate(
0164   rtems_profiling_visitor visitor,
0165   void *visitor_arg
0166 )
0167 {
0168   rtems_profiling_data data;
0169 
0170   per_cpu_stats_iterate(visitor, visitor_arg, &data);
0171   smp_lock_stats_iterate(visitor, visitor_arg, &data);
0172 }