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

4.104.114.84.95
Last change on this file since c3330a8 was c3330a8, checked in by Joel Sherrill <joel.sherrill@…>, on May 17, 2007 at 10:46:45 PM

2007-05-17 Joel Sherrill <joel.sherrill@…>

  • ChangeLog?, configure.ac, libcsupport/src/times.c, libmisc/cpuuse/cpuuse.c, libmisc/stackchk/check.c, rtems/include/rtems/rtems/ratemon.h, rtems/src/ratemongetstatus.c, rtems/src/ratemonperiod.c, rtems/src/ratemonreportstatistics.c, rtems/src/ratemonresetall.c, rtems/src/ratemontimeout.c, score/Makefile.am, score/include/rtems/score/thread.h, score/include/rtems/score/timespec.h, score/src/threaddispatch.c, score/src/threadinitialize.c, score/src/threadtickletimeslice.c, score/src/timespecdivide.c: Add nanoseconds granularity to the rate monotonic period statistics and CPU usage statistics. This capability is enabled by default although may be conditionally disabled by the user. It could be too much overhead on small targets but it does not appear to be bad in early testing. Its impact on code size has not been evaluated either. It is possible that both forms of statistics gathering could be disabled with further tweaking of the conditional compilation.
  • score/src/timespecdividebyinteger.c: New file.
  • Property mode set to 100644
File size: 5.3 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 100000
31  #define PERCENT_FMT "%04" PRId32
32#endif
33
34/*
35 *  This directive allows a thread to print the statistics information
36 *  on ALL period instances which have non-zero counts using printk.
37 *
38 *  The implementation of this directive straddles the fence between
39 *  inside and outside of RTEMS.  It is presented as part of the Manager
40 *  but actually uses other services of the Manager.
41 */
42void rtems_rate_monotonic_report_statistics( void )
43{
44  rtems_status_code                      status;
45  rtems_id                               id;
46  rtems_rate_monotonic_period_statistics the_stats;
47  rtems_rate_monotonic_period_status     the_status;
48  char                                   name[5];
49
50  printk( "Period information by period\n" );
51/*
52Layout by columns -- in memory of Hollerith :)
53
541234567890123456789012345678901234567890123456789012345678901234567890123456789\
55   ID     OWNER COUNT MISSED X
56ididididid NNNN ccccc mmmmmm X
57
58  Uncomment the following if you are tinkering with the formatting.
59  Be sure to test the various cases.
60  printk("\
611234567890123456789012345678901234567890123456789012345678901234567890123456789\
62\n");
63*/
64  printk( "   ID     OWNER COUNT MISSED     CPU TIME     "
65       #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
66          "    "
67       #endif
68       #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS
69          "   "
70       #endif
71          "   WALL TIME\n"
72  );
73
74  /*
75   * Cycle through all possible ids and try to report on each one.  If it
76   * is a period that is inactive, we just get an error back.  No big deal.
77   */
78  for ( id=_Rate_monotonic_Information.minimum_id ;
79        id <= _Rate_monotonic_Information.maximum_id ;
80        id++ ) {
81    status = rtems_rate_monotonic_get_statistics( id, &the_stats );
82    if ( status != RTEMS_SUCCESSFUL )
83      continue;
84   
85    /* If the above passed, so should this but check it anyway */
86    status = rtems_rate_monotonic_get_status( id, &the_status );
87    if ( status != RTEMS_SUCCESSFUL )
88      continue;
89   
90    if ( the_stats.count == 0 )
91      continue;
92
93    name[ 0 ] = '\0';
94
95    if ( the_status.owner ) {
96      rtems_object_get_name( the_status.owner, sizeof(name), name );
97    }
98
99    /*
100     *  Print part of report line that is not dependent on granularity
101     */
102
103    printk(
104      "0x%08" PRIx32 " %4s %5" PRId32 " %6" PRId32 " ",
105      id, name,
106      the_stats.count, the_stats.missed_count
107    );
108
109    /*
110     *  print CPU Usage part of statistics
111     */
112    {
113    #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
114      struct timespec   cpu_average;
115
116      _Timespec_Divide_by_integer(
117         &the_stats.total_cpu_time,
118         the_stats.count,
119         &cpu_average
120      );
121      printk(
122        "%" PRId32 "." PERCENT_FMT "/"        /* min cpu time */
123        "%" PRId32 "." PERCENT_FMT "/"        /* max cpu time */
124        "%" PRId32 "." PERCENT_FMT " ",       /* avg cpu time */
125        the_stats.min_cpu_time.tv_sec, 
126          the_stats.min_cpu_time.tv_nsec / NANOSECONDS_DIVIDER,
127        the_stats.max_cpu_time.tv_sec,
128          the_stats.max_cpu_time.tv_nsec / NANOSECONDS_DIVIDER,
129        cpu_average.tv_sec,
130          cpu_average.tv_nsec / NANOSECONDS_DIVIDER
131       );
132    #else
133      uint32_t ival_cpu, fval_cpu;
134
135      ival_cpu = the_stats.total_cpu_time * 100 / the_stats.count;
136      fval_cpu = ival_cpu % 100;
137      ival_cpu /= 100;
138
139      printk(
140        "%3" PRId32 "/%4" PRId32 "/%3" PRId32 ".%02" PRId32 " ",
141        the_stats.min_cpu_time, the_stats.max_cpu_time, ival_cpu, fval_cpu
142      );
143    #endif
144    }
145
146    /*
147     *  print Wall time part of statistics
148     */
149    {
150    #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS
151      struct timespec  wall_average;
152      _Timespec_Divide_by_integer(
153         &the_stats.total_wall_time,
154         the_stats.count,
155         &wall_average
156      );
157      printk(
158        "%" PRId32 "." PERCENT_FMT "/"        /* min wall time */
159        "%" PRId32 "." PERCENT_FMT "/"        /* max wall time */
160        "%" PRId32 "." PERCENT_FMT "\n",      /* avg wall time */
161        the_stats.min_wall_time.tv_sec, 
162          the_stats.min_wall_time.tv_nsec / NANOSECONDS_DIVIDER,
163        the_stats.max_wall_time.tv_sec,
164          the_stats.max_wall_time.tv_nsec / NANOSECONDS_DIVIDER,
165        wall_average.tv_sec,
166          wall_average.tv_nsec / NANOSECONDS_DIVIDER
167      );
168    #else
169      uint32_t  ival_wall, fval_wall;
170
171      ival_wall = the_stats.total_wall_time * 100 / the_stats.count;
172      fval_wall = ival_wall % 100;
173      ival_wall /= 100;
174      printk(
175        "%3" PRId32 "/%4" PRId32 "/%3" PRId32 ".%02" PRId32 "\n",
176        the_stats.min_wall_time, the_stats.max_wall_time, ival_wall, fval_wall
177      );
178    #endif
179    }
180  }
181}
Note: See TracBrowser for help on using the repository browser.