source: rtems/cpukit/libmisc/cpuuse/cpuusagereport.c @ 00735ee

4.104.11
Last change on this file since 00735ee was 00735ee, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 11, 2009 at 4:28:06 PM

2009-11-11 Jennifer Averett <jennifer.averett@…>

PR 1471/cpukit

  • libmisc/cpuuse/cpuusagereport.c: Rework statement to ensure 64-bit multiplication is used to avoid overflow with intermediate value.
  • Property mode set to 100644
File size: 5.9 KB
Line 
1/*
2 *  CPU Usage Reporter
3 *
4 *  COPYRIGHT (c) 1989-2007
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.com/license/LICENSE.
10 *
11 *  $Id$
12 */
13
14#ifdef HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <rtems.h>
19
20#include <assert.h>
21#include <string.h>
22#include <stdlib.h>
23#include <stdio.h>
24#include <ctype.h>
25#include <inttypes.h>
26
27#include <rtems/cpuuse.h>
28#include <rtems/bspIo.h>
29
30#if defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
31  #include <rtems/score/timestamp.h>
32#endif
33
34#ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
35  extern Timestamp_Control  CPU_usage_Uptime_at_last_reset;
36#else
37  extern uint32_t           CPU_usage_Ticks_at_last_reset;
38#endif
39
40/*PAGE
41 *
42 *  rtems_cpu_usage_report
43 */
44
45void rtems_cpu_usage_report_with_plugin(
46  void                  *context,
47  rtems_printk_plugin_t  print
48)
49{
50  uint32_t             i;
51  uint32_t             api_index;
52  Thread_Control      *the_thread;
53  Objects_Information *information;
54  char                 name[13];
55  uint32_t             ival, fval;
56  #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
57    Timestamp_Control  uptime, total, ran;
58  #else
59    uint32_t           total_units = 0;
60  #endif
61
62  if ( !print )
63    return;
64
65  /*
66   *  When not using nanosecond CPU usage resolution, we have to count
67   *  the number of "ticks" we gave credit for to give the user a rough
68   *  guideline as to what each number means proportionally.
69   */
70  #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
71    _TOD_Get_uptime( &uptime );
72    _Timestamp_Subtract( &CPU_usage_Uptime_at_last_reset, &uptime, &total );
73  #else
74    for ( api_index = 1 ; api_index <= OBJECTS_APIS_LAST ; api_index++ ) {
75      if ( !_Objects_Information_table[ api_index ] )
76        continue;
77      information = _Objects_Information_table[ api_index ][ 1 ];
78      if ( information ) {
79        for ( i=1 ; i <= information->maximum ; i++ ) {
80          the_thread = (Thread_Control *)information->local_table[ i ];
81
82          if ( the_thread )
83            total_units += the_thread->cpu_time_used;
84        }
85      }
86    }
87  #endif
88 
89  (*print)(
90     context,
91     "-------------------------------------------------------------------------------\n"
92     "                              CPU USAGE BY THREAD\n"
93     "------------+----------------------------------------+---------------+---------\n"
94     #if defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
95       " ID         | NAME                                   | SECONDS       | PERCENT\n"
96     #else
97       " ID         | NAME                                   | TICKS         | PERCENT\n"
98     #endif
99     "------------+----------------------------------------+---------------+---------\n"
100  );
101
102  for ( api_index = 1 ;
103        api_index <= OBJECTS_APIS_LAST ;
104        api_index++ ) {
105    if ( !_Objects_Information_table[ api_index ] )
106      continue;
107    information = _Objects_Information_table[ api_index ][ 1 ];
108    if ( information ) {
109      for ( i=1 ; i <= information->maximum ; i++ ) {
110        the_thread = (Thread_Control *)information->local_table[ i ];
111
112        if ( !the_thread )
113          continue;
114
115        rtems_object_get_name( the_thread->Object.id, sizeof(name), name );
116 
117        (*print)(
118          context,
119          " 0x%08" PRIx32 " | %-38s |",
120          the_thread->Object.id,
121          name
122        );
123
124        #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
125          /*
126           * If this is the currently executing thread, account for time
127           * since the last context switch.
128           */
129          ran = the_thread->cpu_time_used;
130          if ( _Thread_Executing->Object.id == the_thread->Object.id ) {
131            Timestamp_Control used;
132            _Timestamp_Subtract(
133              &_Thread_Time_of_last_context_switch, &uptime, &used
134            );
135            _Timestamp_Add_to( &ran, &used );
136          };
137          _Timestamp_Divide( &ran, &total, &ival, &fval );
138
139          /*
140           * Print the information
141           */
142
143          (*print)( context,
144            "%7" PRIu32 ".%06" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n",
145            _Timestamp_Get_seconds( &ran ),
146            _Timestamp_Get_nanoseconds( &ran ) /
147               TOD_NANOSECONDS_PER_MICROSECOND,
148            ival, fval
149          );
150        #else
151         if (total_units) {
152            uint64_t ival_64;
153
154            ival_64 = the_thread->cpu_time_used;
155            ival_64 *= 10000;
156            ival = ival_64 / total_units;
157          } else {
158            ival = 0;
159          }
160
161          fval = ival % 1000;
162          ival /= 1000;
163          (*print)( context,
164            "%14" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n",
165            the_thread->cpu_time_used,
166            ival,
167            fval
168          );
169        #endif
170      }
171    }
172  }
173
174  #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
175    (*print)(
176       context,
177       "------------+----------------------------------------+---------------+---------\n"
178       " TIME SINCE LAST CPU USAGE RESET IN SECONDS:                    %7" PRIu32 ".%06" PRIu32 "\n"
179       "-------------------------------------------------------------------------------\n",
180       _Timestamp_Get_seconds( &total ),
181       _Timestamp_Get_nanoseconds( &total ) / TOD_NANOSECONDS_PER_MICROSECOND
182    );
183  #else
184    (*print)(
185       context,
186       "------------+----------------------------------------+---------------+---------\n"
187       " TICKS SINCE LAST SYSTEM RESET:                                 %14" PRIu32 "\n"
188       " TOTAL UNITS:                                                   %14" PRIu32 "\n"
189       "-------------------------------------------------------------------------------\n",
190       _Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset,
191       total_units
192    );
193  #endif
194}
195
196void rtems_cpu_usage_report( void )
197{
198  rtems_cpu_usage_report_with_plugin( NULL, printk_plugin );
199}
Note: See TracBrowser for help on using the repository browser.