source: rtems/cpukit/libmisc/cpuuse/cpuusagereport.c @ db498aba

4.115
Last change on this file since db498aba was db498aba, checked in by Sebastian Huber <sebastian.huber@…>, on 03/07/11 at 14:55:05

2011-03-07 Sebastian Huber <sebastian.huber@…>

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