Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSImplCPUUsageReporting
0007  *
0008  * @brief This source file contains the definition of
0009  *   rtems_cpu_usage_report() and rtems_cpu_usage_report_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 <string.h>
0043 #include <stdlib.h>
0044 #include <stdio.h>
0045 #include <ctype.h>
0046 #include <inttypes.h>
0047 
0048 #include <rtems/cpuuse.h>
0049 #include <rtems/printer.h>
0050 #include <rtems/score/threadimpl.h>
0051 #include <rtems/score/todimpl.h>
0052 
0053 #include "cpuuseimpl.h"
0054 
0055 typedef struct {
0056   const rtems_printer *printer;
0057   Timestamp_Control    total;
0058   Timestamp_Control    uptime_at_last_reset;
0059 } cpu_usage_context;
0060 
0061 static bool cpu_usage_visitor( Thread_Control *the_thread, void *arg )
0062 {
0063   cpu_usage_context *ctx;
0064   char               name[ 38 ];
0065   uint32_t           ival;
0066   uint32_t           fval;
0067   Timestamp_Control  uptime;
0068   Timestamp_Control  used;
0069   uint32_t           seconds;
0070   uint32_t           nanoseconds;
0071 
0072   ctx = arg;
0073   _Thread_Get_name( the_thread, name, sizeof( name ) );
0074 
0075   used = _Thread_Get_CPU_time_used_after_last_reset( the_thread );
0076   _TOD_Get_uptime( &uptime );
0077   _Timestamp_Subtract( &ctx->uptime_at_last_reset, &uptime, &ctx->total );
0078   _Timestamp_Divide( &used, &ctx->total, &ival, &fval );
0079   seconds = _Timestamp_Get_seconds( &used );
0080   nanoseconds = _Timestamp_Get_nanoseconds( &used ) /
0081     TOD_NANOSECONDS_PER_MICROSECOND;
0082 
0083   rtems_printf(
0084     ctx->printer,
0085     " 0x%08" PRIx32 " | %-38s |"
0086       "%7" PRIu32 ".%06" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n",
0087     the_thread->Object.id,
0088     name,
0089     seconds, nanoseconds,
0090     ival, fval
0091   );
0092 
0093   return false;
0094 }
0095 
0096 /*
0097  *  rtems_cpu_usage_report
0098  */
0099 void rtems_cpu_usage_report_with_plugin(
0100   const rtems_printer *printer
0101 )
0102 {
0103   cpu_usage_context  ctx;
0104   uint32_t           seconds;
0105   uint32_t           nanoseconds;
0106 
0107   ctx.printer = printer;
0108 
0109   /*
0110    *  When not using nanosecond CPU usage resolution, we have to count
0111    *  the number of "ticks" we gave credit for to give the user a rough
0112    *  guideline as to what each number means proportionally.
0113    */
0114   _Timestamp_Set_to_zero( &ctx.total );
0115   ctx.uptime_at_last_reset = CPU_usage_Uptime_at_last_reset;
0116 
0117   rtems_printf(
0118      printer,
0119      "-------------------------------------------------------------------------------\n"
0120      "                              CPU USAGE BY THREAD\n"
0121      "------------+----------------------------------------+---------------+---------\n"
0122      " ID         | NAME                                   | SECONDS       | PERCENT\n"
0123      "------------+----------------------------------------+---------------+---------\n"
0124   );
0125 
0126   rtems_task_iterate( cpu_usage_visitor, &ctx );
0127 
0128   seconds = _Timestamp_Get_seconds( &ctx.total );
0129   nanoseconds = _Timestamp_Get_nanoseconds( &ctx.total ) /
0130     TOD_NANOSECONDS_PER_MICROSECOND;
0131   rtems_printf(
0132      printer,
0133      "------------+----------------------------------------+---------------+---------\n"
0134      " TIME SINCE LAST CPU USAGE RESET IN SECONDS:                    %7" PRIu32 ".%06" PRIu32 "\n"
0135      "-------------------------------------------------------------------------------\n",
0136      seconds, nanoseconds
0137   );
0138 }
0139 
0140 void rtems_cpu_usage_report( void )
0141 {
0142   rtems_printer printer;
0143   rtems_print_printer_printk( &printer );
0144   rtems_cpu_usage_report_with_plugin( &printer );
0145 }