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 RTEMSImplClassicRateMonotonic
0007  *
0008  * @brief This source file contains the implementation of
0009  *   rtems_rate_monotonic_report_statistics_with_plugin().
0010  */
0011 
0012 /*
0013  *  COPYRIGHT (c) 1989-2010.
0014  *  On-Line Applications Research Corporation (OAR).
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041 
0042 #include <rtems/rtems/ratemonimpl.h>
0043 #include <rtems/rtems/object.h>
0044 #include <rtems/printer.h>
0045 
0046 #include <inttypes.h>
0047 #include <rtems/inttypes.h>
0048 
0049 /* We print to 1/10's of milliseconds */
0050 #define NANOSECONDS_DIVIDER 1000L
0051 #define PERCENT_FMT     "%04" PRId32
0052 #define NANOSECONDS_FMT "%06ld"
0053 
0054 void rtems_rate_monotonic_report_statistics_with_plugin(
0055   const rtems_printer *printer
0056 )
0057 {
0058   rtems_status_code                      status;
0059   rtems_id                               maximum_id;
0060   rtems_id                               id;
0061   rtems_rate_monotonic_period_statistics the_stats;
0062   rtems_rate_monotonic_period_status     the_status;
0063   char                                   name[5];
0064 
0065   rtems_printf( printer, "Period information by period\n" );
0066   rtems_printf( printer, "--- CPU times are in seconds ---\n" );
0067   rtems_printf( printer, "--- Wall times are in seconds ---\n" );
0068 /*
0069 Layout by columns -- in memory of Hollerith :)
0070 
0071 1234567890123456789012345678901234567890123456789012345678901234567890123456789\
0072    ID     OWNER COUNT MISSED X
0073 ididididid NNNN ccccc mmmmmm X
0074 
0075   Uncomment the following if you are tinkering with the formatting.
0076   Be sure to test the various cases.
0077   (*print)( context,"\
0078 1234567890123456789012345678901234567890123456789012345678901234567890123456789\
0079 \n");
0080 */
0081   rtems_printf( printer,
0082       "   ID     OWNER COUNT MISSED     "
0083       "     CPU TIME                  WALL TIME\n"
0084       "                               "
0085       "     MIN/MAX/AVG                MIN/MAX/AVG\n"
0086   );
0087 
0088   /*
0089    * Cycle through all possible ids and try to report on each one.  If it
0090    * is a period that is inactive, we just get an error back.  No big deal.
0091    */
0092   maximum_id = _Rate_monotonic_Information.maximum_id;
0093   for (
0094     id = _Objects_Get_minimum_id( maximum_id ) ;
0095     id <= maximum_id ;
0096     ++id
0097   ) {
0098     status = rtems_rate_monotonic_get_statistics( id, &the_stats );
0099     if ( status != RTEMS_SUCCESSFUL )
0100       continue;
0101 
0102     /* If the above passed, so should this but check it anyway */
0103     #if defined(RTEMS_DEBUG)
0104       status = rtems_rate_monotonic_get_status( id, &the_status );
0105       if ( status != RTEMS_SUCCESSFUL )
0106         continue;
0107     #else
0108       (void) rtems_rate_monotonic_get_status( id, &the_status );
0109     #endif
0110 
0111     rtems_object_get_name( the_status.owner, sizeof(name), name );
0112 
0113     /*
0114      *  Print part of report line that is not dependent on granularity
0115      */
0116     rtems_printf( printer,
0117       "0x%08" PRIx32 " %4s %5" PRId32 " %6" PRId32 " ",
0118       id, name,
0119       the_stats.count, the_stats.missed_count
0120     );
0121 
0122     /*
0123      *  If the count is zero, don't print statistics
0124      */
0125     if (the_stats.count == 0) {
0126       rtems_printf( printer, "\n" );
0127       continue;
0128     }
0129 
0130     /*
0131      *  print CPU Usage part of statistics
0132      */
0133     {
0134       struct timespec  cpu_average;
0135       struct timespec *min_cpu = &the_stats.min_cpu_time;
0136       struct timespec *max_cpu = &the_stats.max_cpu_time;
0137       struct timespec *total_cpu = &the_stats.total_cpu_time;
0138 
0139       _Timespec_Divide_by_integer( total_cpu, the_stats.count, &cpu_average );
0140       rtems_printf( printer,
0141         "%" PRIdtime_t "."  NANOSECONDS_FMT "/"        /* min cpu time */
0142         "%" PRIdtime_t "."  NANOSECONDS_FMT "/"        /* max cpu time */
0143         "%" PRIdtime_t "."  NANOSECONDS_FMT " ",       /* avg cpu time */
0144         _Timespec_Get_seconds( min_cpu ),
0145       _Timespec_Get_nanoseconds( min_cpu ) / NANOSECONDS_DIVIDER,
0146         _Timespec_Get_seconds( max_cpu ),
0147       _Timespec_Get_nanoseconds( max_cpu ) / NANOSECONDS_DIVIDER,
0148         _Timespec_Get_seconds( &cpu_average ),
0149       _Timespec_Get_nanoseconds( &cpu_average ) / NANOSECONDS_DIVIDER
0150        );
0151     }
0152 
0153     /*
0154      *  print wall time part of statistics
0155      */
0156     {
0157       struct timespec  wall_average;
0158       struct timespec *min_wall = &the_stats.min_wall_time;
0159       struct timespec *max_wall = &the_stats.max_wall_time;
0160       struct timespec *total_wall = &the_stats.total_wall_time;
0161 
0162       _Timespec_Divide_by_integer(total_wall, the_stats.count, &wall_average);
0163       rtems_printf( printer,
0164         "%" PRIdtime_t "." NANOSECONDS_FMT "/"        /* min wall time */
0165         "%" PRIdtime_t "." NANOSECONDS_FMT "/"        /* max wall time */
0166         "%" PRIdtime_t "." NANOSECONDS_FMT "\n",      /* avg wall time */
0167         _Timespec_Get_seconds( min_wall ),
0168           _Timespec_Get_nanoseconds( min_wall ) / NANOSECONDS_DIVIDER,
0169         _Timespec_Get_seconds( max_wall ),
0170           _Timespec_Get_nanoseconds( max_wall ) / NANOSECONDS_DIVIDER,
0171         _Timespec_Get_seconds( &wall_average ),
0172           _Timespec_Get_nanoseconds( &wall_average ) / NANOSECONDS_DIVIDER
0173       );
0174     }
0175   }
0176 }
0177 
0178 void rtems_rate_monotonic_report_statistics( void )
0179 {
0180   rtems_printer printer;
0181   rtems_print_printer_printk( &printer );
0182   rtems_rate_monotonic_report_statistics_with_plugin( &printer );
0183 }