source: rtems/cpukit/rtems/src/ratemonreportstatistics.c @ 90a5d194

4.104.114.84.95
Last change on this file since 90a5d194 was 90a5d194, checked in by Joel Sherrill <joel.sherrill@…>, on 09/06/07 at 22:51:25

2007-09-06 Joel Sherrill <joel.sherrill@…>

  • libcsupport/Makefile.am, libcsupport/src/printk.c:
  • libcsupport/src/printk_plugin.c: New file. include/rtems/bspIo.h, libmisc/cpuuse/cpuusagereport.c, libmisc/cpuuse/cpuuse.h, libmisc/stackchk/check.c, libmisc/stackchk/stackchk.h: rtems/include/rtems/rtems/ratemon.h, rtems/src/ratemonreportstatistics.c: Added capability to specify your own "printf" routine to various reporting functions. This added an XXX_with_plugin as the underlying implementation for + rtems_rate_monotonic_report_statistics + rtems_stack_checker_report_usage + rtems_cpu_usage_report As demonstration, the http netdemo can now print out stack and cpu usage reports.
  • Property mode set to 100644
File size: 6.0 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 "%" 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_RATE_MONOTONIC_STATISTICS)
59  (*print)( context, "--- Period times are seconds:microseconds ---\n" );
60#endif
61   
62#if defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
63  (*print)( context, "--- CPU Usage times are seconds:microseconds ---\n" );
64#endif
65/*
66Layout by columns -- in memory of Hollerith :)
67
681234567890123456789012345678901234567890123456789012345678901234567890123456789\
69   ID     OWNER COUNT MISSED X
70ididididid NNNN ccccc mmmmmm X
71
72  Uncomment the following if you are tinkering with the formatting.
73  Be sure to test the various cases.
74*/
75  (*print)( context,"\
761234567890123456789012345678901234567890123456789012345678901234567890123456789\
77\n");
78  (*print)( context, "   ID     OWNER COUNT MISSED     CPU TIME     "
79       #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
80          "    "
81       #endif
82       #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS
83          "   "
84       #endif
85          "   WALL TIME\n"
86  );
87
88  /*
89   * Cycle through all possible ids and try to report on each one.  If it
90   * is a period that is inactive, we just get an error back.  No big deal.
91   */
92  for ( id=_Rate_monotonic_Information.minimum_id ;
93        id <= _Rate_monotonic_Information.maximum_id ;
94        id++ ) {
95    status = rtems_rate_monotonic_get_statistics( id, &the_stats );
96    if ( status != RTEMS_SUCCESSFUL )
97      continue;
98   
99    /* If the above passed, so should this but check it anyway */
100    status = rtems_rate_monotonic_get_status( id, &the_status );
101    if ( status != RTEMS_SUCCESSFUL )
102      continue;
103   
104    if ( the_stats.count == 0 )
105      continue;
106
107    name[ 0 ] = '\0';
108
109    if ( the_status.owner ) {
110      rtems_object_get_name( the_status.owner, sizeof(name), name );
111    }
112
113    /*
114     *  Print part of report line that is not dependent on granularity
115     */
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     *  print CPU Usage part of statistics
125     */
126    {
127    #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
128      struct timespec   cpu_average;
129
130      _Timespec_Divide_by_integer(
131         &the_stats.total_cpu_time,
132         the_stats.count,
133         &cpu_average
134      );
135      (*print)( context,
136        "%" PRId32 ":"  NANOSECONDS_FMT "/"        /* min cpu time */
137        "%" PRId32 ":"  NANOSECONDS_FMT "/"        /* max cpu time */
138        "%" PRId32 ":"  NANOSECONDS_FMT " ",       /* avg cpu time */
139        the_stats.min_cpu_time.tv_sec,
140          the_stats.min_cpu_time.tv_nsec / NANOSECONDS_DIVIDER,
141        the_stats.max_cpu_time.tv_sec,
142          the_stats.max_cpu_time.tv_nsec / NANOSECONDS_DIVIDER,
143        cpu_average.tv_sec,
144          cpu_average.tv_nsec / NANOSECONDS_DIVIDER
145       );
146    #else
147      uint32_t ival_cpu, fval_cpu;
148
149      ival_cpu = the_stats.total_cpu_time * 100 / the_stats.count;
150      fval_cpu = ival_cpu % 100;
151      ival_cpu /= 100;
152
153      (*print)( context,
154        "%3" PRId32 "/%4" PRId32 "/%3" PRId32 ".%02" PRId32 " ",
155        the_stats.min_cpu_time, the_stats.max_cpu_time, ival_cpu, fval_cpu
156      );
157    #endif
158    }
159
160    /*
161     *  print Wall time part of statistics
162     */
163    {
164    #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS
165      struct timespec  wall_average;
166      _Timespec_Divide_by_integer(
167         &the_stats.total_wall_time,
168         the_stats.count,
169         &wall_average
170      );
171      (*print)( context,
172        "%" PRId32 ":" PERCENT_FMT "/"        /* min wall time */
173        "%" PRId32 ":" PERCENT_FMT "/"        /* max wall time */
174        "%" PRId32 ":" PERCENT_FMT "\n",      /* avg wall time */
175        the_stats.min_wall_time.tv_sec,
176          the_stats.min_wall_time.tv_nsec / NANOSECONDS_DIVIDER,
177        the_stats.max_wall_time.tv_sec,
178          the_stats.max_wall_time.tv_nsec / NANOSECONDS_DIVIDER,
179        wall_average.tv_sec,
180          wall_average.tv_nsec / NANOSECONDS_DIVIDER
181      );
182    #else
183      uint32_t  ival_wall, fval_wall;
184
185      ival_wall = the_stats.total_wall_time * 100 / the_stats.count;
186      fval_wall = ival_wall % 100;
187      ival_wall /= 100;
188      (*print)( context,
189        "%3" PRId32 "/%4" PRId32 "/%3" PRId32 ".%02" PRId32 "\n",
190        the_stats.min_wall_time, the_stats.max_wall_time, ival_wall, fval_wall
191      );
192    #endif
193    }
194  }
195}
196
197void rtems_rate_monotonic_report_statistics( void )
198{
199  rtems_rate_monotonic_report_statistics_with_plugin( NULL, printk_plugin );
200}
Note: See TracBrowser for help on using the repository browser.