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

4.104.114.95
Last change on this file since b0ac06f8 was b0ac06f8, checked in by Glenn Humphrey <glenn.humphrey@…>, on 10/26/07 at 21:30:59

2007-10-26 Glenn Humphrey <glenn.humphrey@…>

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