source: rtems/cpukit/rtems/src/ratemonreportstatistics.c @ dca9a82

4.104.115
Last change on this file since dca9a82 was dca9a82, checked in by Glenn Humphrey <glenn.humphrey@…>, on 12/02/09 at 18:22:19

2009-12-02 Glenn Humphrey <glenn.humphrey@…>

  • libcsupport/src/times.c, libmisc/cpuuse/cpuusagedata.c, libmisc/cpuuse/cpuusagereport.c, libmisc/cpuuse/cpuusagereset.c, rtems/include/rtems/rtems/types.h, rtems/src/ratemongetstatistics.c, rtems/src/ratemonreportstatistics.c, score/src/threaddispatch.c, score/src/threadinitialize.c, score/src/threadtickletimeslice.c: Updated copyright line.
  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2 *  Rate Monotonic Manager -- Report Statistics for All Periods
3 *
4 *  COPYRIGHT (c) 1989-2009.
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#include <stdlib.h>
20#include <ctype.h>
21#include <inttypes.h>
22
23#include <rtems/bspIo.h>
24#include <rtems/score/timespec.h>
25
26#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
27  /* We print to 1/10's of milliseconds */
28  #define NANOSECONDS_DIVIDER 1000
29  #define PERCENT_FMT     "%04" PRId32
30  #define NANOSECONDS_FMT "%06" PRId32
31#endif
32
33/*
34 *  This directive allows a thread to print the statistics information
35 *  on ALL period instances which have non-zero counts using printk.
36 *
37 *  The implementation of this directive straddles the fence between
38 *  inside and outside of RTEMS.  It is presented as part of the Manager
39 *  but actually uses other services of the Manager.
40 */
41void rtems_rate_monotonic_report_statistics_with_plugin(
42  void                  *context,
43  rtems_printk_plugin_t  print
44)
45{
46  rtems_status_code                      status;
47  rtems_id                               id;
48  rtems_rate_monotonic_period_statistics the_stats;
49  rtems_rate_monotonic_period_status     the_status;
50  char                                   name[5];
51
52  if ( !print )
53    return;
54
55  (*print)( context, "Period information by period\n" );
56  #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
57    (*print)( context, "--- CPU times are in seconds ---\n" );
58    (*print)( context, "--- Wall times are in seconds ---\n" );
59  #endif
60/*
61Layout by columns -- in memory of Hollerith :)
62
631234567890123456789012345678901234567890123456789012345678901234567890123456789\
64   ID     OWNER COUNT MISSED X
65ididididid NNNN ccccc mmmmmm X
66
67  Uncomment the following if you are tinkering with the formatting.
68  Be sure to test the various cases.
69  (*print)( context,"\
701234567890123456789012345678901234567890123456789012345678901234567890123456789\
71\n");
72*/
73  (*print)( context, "   ID     OWNER COUNT MISSED     "
74       #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
75          "     "
76       #endif
77          "CPU TIME     "
78       #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
79          "          "
80       #endif
81          "   WALL TIME\n"
82  );
83  (*print)( context, "                               "
84       #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
85          "     "
86       #endif
87          "MIN/MAX/AVG    "
88       #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
89          "          "
90       #endif
91          "  MIN/MAX/AVG\n"
92  );
93
94  /*
95   * Cycle through all possible ids and try to report on each one.  If it
96   * is a period that is inactive, we just get an error back.  No big deal.
97   */
98  for ( id=_Rate_monotonic_Information.minimum_id ;
99        id <= _Rate_monotonic_Information.maximum_id ;
100        id++ ) {
101    status = rtems_rate_monotonic_get_statistics( id, &the_stats );
102    if ( status != RTEMS_SUCCESSFUL )
103      continue;
104
105    /* If the above passed, so should this but check it anyway */
106    status = rtems_rate_monotonic_get_status( id, &the_status );
107    #if defined(RTEMS_DEBUG)
108      if ( status != RTEMS_SUCCESSFUL )
109        continue;
110    #endif
111
112    rtems_object_get_name( the_status.owner, sizeof(name), name );
113
114    /*
115     *  Print part of report line that is not dependent on granularity
116     */
117    (*print)( context,
118      "0x%08" PRIx32 " %4s %5" PRId32 " %6" PRId32 " ",
119      id, name,
120      the_stats.count, the_stats.missed_count
121    );
122
123    /*
124     *  If the count is zero, don't print statistics
125     */
126    if (the_stats.count == 0) {
127      (*print)( context, "\n" );
128      continue;
129    }
130
131    /*
132     *  print CPU Usage part of statistics
133     */
134    {
135    #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
136      struct timespec  cpu_average;
137      struct timespec *min_cpu = &the_stats.min_cpu_time;
138      struct timespec *max_cpu = &the_stats.max_cpu_time;
139      struct timespec *total_cpu = &the_stats.total_cpu_time;
140
141      _Timespec_Divide_by_integer( total_cpu, the_stats.count, &cpu_average );
142      (*print)( context,
143        "%" PRId32 "."  NANOSECONDS_FMT "/"        /* min cpu time */
144        "%" PRId32 "."  NANOSECONDS_FMT "/"        /* max cpu time */
145        "%" PRId32 "."  NANOSECONDS_FMT " ",       /* avg cpu time */
146        _Timespec_Get_seconds( min_cpu ),
147          _Timespec_Get_nanoseconds( min_cpu ) / NANOSECONDS_DIVIDER,
148        _Timespec_Get_seconds( max_cpu ),
149          _Timespec_Get_nanoseconds( max_cpu ) / NANOSECONDS_DIVIDER,
150        _Timespec_Get_seconds( &cpu_average ),
151          _Timespec_Get_nanoseconds( &cpu_average ) / NANOSECONDS_DIVIDER
152       );
153    #else
154      uint32_t ival_cpu, fval_cpu;
155
156      ival_cpu = the_stats.total_cpu_time * 100 / the_stats.count;
157      fval_cpu = ival_cpu % 100;
158      ival_cpu /= 100;
159
160      (*print)( context,
161        "%3" PRId32 "/%4" PRId32 "/%3" PRId32 ".%02" PRId32 " ",
162        the_stats.min_cpu_time, the_stats.max_cpu_time, ival_cpu, fval_cpu
163      );
164    #endif
165    }
166
167    /*
168     *  print wall time part of statistics
169     */
170    {
171    #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
172      struct timespec  wall_average;
173      struct timespec *min_wall = &the_stats.min_wall_time;
174      struct timespec *max_wall = &the_stats.max_wall_time;
175      struct timespec *total_wall = &the_stats.total_wall_time;
176
177      _Timespec_Divide_by_integer(total_wall, the_stats.count, &wall_average);
178      (*print)( context,
179        "%" PRId32 "." NANOSECONDS_FMT "/"        /* min wall time */
180        "%" PRId32 "." NANOSECONDS_FMT "/"        /* max wall time */
181        "%" PRId32 "." NANOSECONDS_FMT "\n",      /* avg wall time */
182        _Timespec_Get_seconds( min_wall ),
183          _Timespec_Get_nanoseconds( min_wall ) / NANOSECONDS_DIVIDER,
184        _Timespec_Get_seconds( max_wall ),
185          _Timespec_Get_nanoseconds( max_wall ) / NANOSECONDS_DIVIDER,
186        _Timespec_Get_seconds( &wall_average ),
187          _Timespec_Get_nanoseconds( &wall_average ) / NANOSECONDS_DIVIDER
188      );
189    #else
190      uint32_t  ival_wall, fval_wall;
191
192      ival_wall = the_stats.total_wall_time * 100 / the_stats.count;
193      fval_wall = ival_wall % 100;
194      ival_wall /= 100;
195      (*print)( context,
196        "%3" PRId32 "/%4" PRId32 "/%3" PRId32 ".%02" PRId32 "\n",
197        the_stats.min_wall_time, the_stats.max_wall_time, ival_wall, fval_wall
198      );
199    #endif
200    }
201  }
202}
203
204void rtems_rate_monotonic_report_statistics( void )
205{
206  rtems_rate_monotonic_report_statistics_with_plugin( NULL, printk_plugin );
207}
Note: See TracBrowser for help on using the repository browser.