source: rtems/cpukit/libmisc/cpuuse/cpuusagereport.c @ 4e21c9a

4.11
Last change on this file since 4e21c9a was 4e21c9a, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 16, 2010 at 3:46:34 PM

2010-12-16 Sebastian Huber <sebastian.huber@…>

  • libmisc/cpuuse/cpuusagereport.c: We have to take the time since the last context switch before the uptime.
  • Property mode set to 100644
File size: 6.0 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, last_context_switch;
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    last_context_switch = _Thread_Time_of_last_context_switch;
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 !defined(RTEMS_POSIX_API) || defined(RTEMS_DEBUG)
76        if ( !_Objects_Information_table[ api_index ] )
77          continue;
78      #endif
79
80      information = _Objects_Information_table[ api_index ][ 1 ];
81      if ( information ) {
82        for ( i=1 ; i <= information->maximum ; i++ ) {
83          the_thread = (Thread_Control *)information->local_table[ i ];
84
85          if ( the_thread )
86            total_units += the_thread->cpu_time_used;
87        }
88      }
89    }
90  #endif
91
92  (*print)(
93     context,
94     "-------------------------------------------------------------------------------\n"
95     "                              CPU USAGE BY THREAD\n"
96     "------------+----------------------------------------+---------------+---------\n"
97     #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
98       " ID         | NAME                                   | SECONDS       | PERCENT\n"
99     #else
100       " ID         | NAME                                   | TICKS         | PERCENT\n"
101     #endif
102     "------------+----------------------------------------+---------------+---------\n"
103  );
104
105  for ( api_index = 1 ; api_index <= OBJECTS_APIS_LAST ; api_index++ ) {
106    #if !defined(RTEMS_POSIX_API) || defined(RTEMS_DEBUG)
107      if ( !_Objects_Information_table[ api_index ] )
108        continue;
109    #endif
110
111    information = _Objects_Information_table[ api_index ][ 1 ];
112    if ( information ) {
113      for ( i=1 ; i <= information->maximum ; i++ ) {
114        the_thread = (Thread_Control *)information->local_table[ i ];
115
116        if ( !the_thread )
117          continue;
118
119        rtems_object_get_name( the_thread->Object.id, sizeof(name), name );
120
121        (*print)(
122          context,
123          " 0x%08" PRIx32 " | %-38s |",
124          the_thread->Object.id,
125          name
126        );
127
128        #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
129          /*
130           * If this is the currently executing thread, account for time
131           * since the last context switch.
132           */
133          ran = the_thread->cpu_time_used;
134          if ( _Thread_Executing->Object.id == the_thread->Object.id ) {
135            Timestamp_Control used;
136            _Timestamp_Subtract( &last_context_switch, &uptime, &used );
137            _Timestamp_Add_to( &ran, &used );
138          };
139          _Timestamp_Divide( &ran, &total, &ival, &fval );
140
141          /*
142           * Print the information
143           */
144
145          (*print)( context,
146            "%7" PRIu32 ".%06" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n",
147            _Timestamp_Get_seconds( &ran ),
148            _Timestamp_Get_nanoseconds( &ran ) /
149               TOD_NANOSECONDS_PER_MICROSECOND,
150            ival, fval
151          );
152        #else
153         if (total_units) {
154            uint64_t ival_64;
155
156            ival_64 = the_thread->cpu_time_used;
157            ival_64 *= 100000;
158            ival = ival_64 / total_units;
159          } else {
160            ival = 0;
161          }
162
163          fval = ival % 1000;
164          ival /= 1000;
165          (*print)( context,
166            "%14" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n",
167            the_thread->cpu_time_used,
168            ival,
169            fval
170          );
171        #endif
172      }
173    }
174  }
175
176  #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
177    (*print)(
178       context,
179       "------------+----------------------------------------+---------------+---------\n"
180       " TIME SINCE LAST CPU USAGE RESET IN SECONDS:                    %7" PRIu32 ".%06" PRIu32 "\n"
181       "-------------------------------------------------------------------------------\n",
182       _Timestamp_Get_seconds( &total ),
183       _Timestamp_Get_nanoseconds( &total ) / TOD_NANOSECONDS_PER_MICROSECOND
184    );
185  #else
186    (*print)(
187       context,
188       "------------+----------------------------------------+---------------+---------\n"
189       " TICKS SINCE LAST SYSTEM RESET:                                 %14" PRIu32 "\n"
190       " TOTAL UNITS:                                                   %14" PRIu32 "\n"
191       "-------------------------------------------------------------------------------\n",
192       _Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset,
193       total_units
194    );
195  #endif
196}
197
198void rtems_cpu_usage_report( void )
199{
200  rtems_cpu_usage_report_with_plugin( NULL, printk_plugin );
201}
Note: See TracBrowser for help on using the repository browser.