source: rtems/cpukit/rtems/src/ratemonperiod.c @ e6b31b27

4.115
Last change on this file since e6b31b27 was e6b31b27, checked in by Joel Sherrill <joel.sherrill@…>, on 05/27/15 at 15:13:58

Remove use ticks for statistics configure option.

This was obsolete and broken based upon recent time keeping changes.

Thie build option was previously enabled by adding
USE_TICKS_FOR_STATISTICS=1 to the configure command line.

This propagated into the code as preprocessor conditionals
using the RTEMS_USE_TICKS_FOR_STATISTICS conditional.

  • Property mode set to 100644
File size: 9.6 KB
RevLine 
[c05d7502]1/**
2 *  @file
[5f9b3db]3 *
[c05d7502]4 *  @brief Rate Monotonic Support
5 *  @ingroup ClassicRateMon
6 */
7
8/*
[7eef54e]9 *  COPYRIGHT (c) 1989-2010.
[5f9b3db]10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
[c499856]14 *  http://www.rtems.org/license/LICENSE.
[5f9b3db]15 */
16
[1095ec1]17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
[ecdcf01]21#include <rtems/rtems/ratemonimpl.h>
[c6e21ee1]22#include <rtems/score/schedulerimpl.h>
[5618c37a]23#include <rtems/score/threadimpl.h>
[f031df0e]24#include <rtems/score/todimpl.h>
[4b48ece0]25#include <rtems/score/watchdogimpl.h>
[5f9b3db]26
[eb37f9d]27bool _Rate_monotonic_Get_status(
28  Rate_monotonic_Control        *the_period,
29  Rate_monotonic_Period_time_t  *wall_since_last_period,
30  Thread_CPU_usage_t            *cpu_since_last_period
31)
32{
[e6b31b27]33  Timestamp_Control        uptime;
34  Thread_Control          *owning_thread = the_period->owner;
35  Thread_CPU_usage_t       used;
[eb37f9d]36
37  /*
38   *  Determine elapsed wall time since period initiated.
39   */
[e6b31b27]40  _TOD_Get_uptime( &uptime );
41  _Timestamp_Subtract(
42    &the_period->time_period_initiated, &uptime, wall_since_last_period
43  );
[eb37f9d]44
45  /*
46   *  Determine cpu usage since period initiated.
47   */
48  used = owning_thread->cpu_time_used;
49
[e6b31b27]50  if (owning_thread == _Thread_Executing) {
51
52    Thread_CPU_usage_t ran;
53
54    /* How much time time since last context switch */
55    _Timestamp_Subtract(
56      &_Thread_Time_of_last_context_switch, &uptime, &ran
57    );
58
59    /* cpu usage += ran */
60    _Timestamp_Add_to( &used, &ran );
61
62    /*
63     *  The cpu usage info was reset while executing.  Can't
64     *  determine a status.
65     */
66    if (_Timestamp_Less_than(&used, &the_period->cpu_usage_period_initiated))
67      return false;
68
69     /* used = current cpu usage - cpu usage at start of period */
70    _Timestamp_Subtract(
71       &the_period->cpu_usage_period_initiated,
72       &used,
73       cpu_since_last_period
74    );
75  }
76
[eb37f9d]77  return true;
78}
79
[94d9bee]80void _Rate_monotonic_Initiate_statistics(
81  Rate_monotonic_Control *the_period
82)
83{
84  Thread_Control *owning_thread = the_period->owner;
85
86  /*
[c6f7e060]87   *  If using nanosecond statistics, we need to obtain the uptime.
[94d9bee]88   */
[c6f7e060]89  #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
90    Timestamp_Control  uptime;
[94d9bee]91
92    _TOD_Get_uptime( &uptime );
93  #endif
94
95  /*
96   *  Set the starting point and the CPU time used for the statistics.
97   */
[c6f7e060]98  #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
[eb37f9d]99    the_period->time_period_initiated = uptime;
[94d9bee]100  #else
[eb37f9d]101    the_period->time_period_initiated = _Watchdog_Ticks_since_boot;
[94d9bee]102  #endif
103
[eb37f9d]104  the_period->cpu_usage_period_initiated = owning_thread->cpu_time_used;
[94d9bee]105
106  /*
[c6f7e060]107   *  If using nanosecond statistics and the period's thread is currently
108   *  executing, then we need to take into account how much time the
109   *  executing thread has run since the last context switch.  When this
110   *  routine is invoked from rtems_rate_monotonic_period, the owner will
111   *  be the executing thread.  When this routine is invoked from
112   *  _Rate_monotonic_Timeout, it will not.
[94d9bee]113   */
[c6f7e060]114  #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
[05c1886]115    if (owning_thread == _Thread_Executing) {
[9e162be9]116      Timestamp_Control ran;
[94d9bee]117
118      /*
119       *  Adjust the CPU time used to account for the time since last
120       *  context switch.
121       */
[9e162be9]122      _Timestamp_Subtract(
[04323c98]123        &_Thread_Time_of_last_context_switch, &uptime, &ran
[94d9bee]124      );
125
[9e162be9]126      _Timestamp_Add_to( &the_period->cpu_usage_period_initiated, &ran );
[94d9bee]127    }
128  #endif
[ac9d2ecc]129
[92635cb]130  _Scheduler_Release_job( the_period->owner, the_period->next_length );
[94d9bee]131}
132
[e31173c]133static void _Rate_monotonic_Update_statistics(
[e1bce86]134  Rate_monotonic_Control    *the_period
135)
136{
[9dc2c8d]137  Thread_CPU_usage_t              executed;
138  Rate_monotonic_Period_time_t    since_last_period;
[eb37f9d]139  Rate_monotonic_Statistics      *stats;
140  bool                            valid_status;
[e1bce86]141
142  /*
143   *  Assume we are only called in states where it is appropriate
144   *  to update the statistics.  This should only be RATE_MONOTONIC_ACTIVE
145   *  and RATE_MONOTONIC_EXPIRED.
146   */
147
148  /*
[94d9bee]149   *  Update the counts.
150   */
151  stats = &the_period->Statistics;
152  stats->count++;
153
154  if ( the_period->state == RATE_MONOTONIC_EXPIRED )
155    stats->missed_count++;
156
157  /*
[eb37f9d]158   *  Grab status for time statistics.
[e1bce86]159   */
[eb37f9d]160  valid_status =
161    _Rate_monotonic_Get_status( the_period, &since_last_period, &executed );
162  if (!valid_status)
163    return;
[e1bce86]164
165  /*
166   *  Update CPU time
167   */
[c6f7e060]168  #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
[c16bcc0]169    _Timestamp_Add_to( &stats->total_cpu_time, &executed );
[c3330a8]170
[05c1886]171    if ( _Timestamp_Less_than( &executed, &stats->min_cpu_time ) )
[c3330a8]172      stats->min_cpu_time = executed;
173
[05c1886]174    if ( _Timestamp_Greater_than( &executed, &stats->max_cpu_time ) )
[c3330a8]175      stats->max_cpu_time = executed;
176  #else
[5fa5185]177    stats->total_cpu_time  += executed;
[e1bce86]178
[5fa5185]179    if ( executed < stats->min_cpu_time )
180      stats->min_cpu_time = executed;
[c3330a8]181
[5fa5185]182    if ( executed > stats->max_cpu_time )
183      stats->max_cpu_time = executed;
[c3330a8]184  #endif
[e1bce86]185
186  /*
187   *  Update Wall time
188   */
[c6f7e060]189  #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
190    _Timestamp_Add_to( &stats->total_wall_time, &since_last_period );
[e1bce86]191
[c6f7e060]192    if ( _Timestamp_Less_than( &since_last_period, &stats->min_wall_time ) )
193      stats->min_wall_time = since_last_period;
194
195    if ( _Timestamp_Greater_than( &since_last_period, &stats->max_wall_time ) )
196      stats->max_wall_time = since_last_period;
197  #else
[a91e372]198
199    /* Sanity check wall time */
200    if ( since_last_period < executed )
201      since_last_period = executed;
202
[5fa5185]203    stats->total_wall_time += since_last_period;
[c3330a8]204
[5fa5185]205    if ( since_last_period < stats->min_wall_time )
206      stats->min_wall_time = since_last_period;
[c3330a8]207
[5fa5185]208    if ( since_last_period > stats->max_wall_time )
209      stats->max_wall_time = since_last_period;
[c3330a8]210  #endif
[e1bce86]211}
212
[5f9b3db]213rtems_status_code rtems_rate_monotonic_period(
[d3b72ca3]214  rtems_id       id,
215  rtems_interval length
[5f9b3db]216)
217{
218  Rate_monotonic_Control              *the_period;
219  Objects_Locations                    location;
220  rtems_status_code                    return_value;
221  rtems_rate_monotonic_period_states   local_state;
222  ISR_Level                            level;
223
224  the_period = _Rate_monotonic_Get( id, &location );
225
[94d9bee]226  switch ( location ) {
[5f9b3db]227    case OBJECTS_LOCAL:
228      if ( !_Thread_Is_executing( the_period->owner ) ) {
[2d2352b]229        _Objects_Put( &the_period->Object );
[5f9b3db]230        return RTEMS_NOT_OWNER_OF_RESOURCE;
231      }
232
233      if ( length == RTEMS_PERIOD_STATUS ) {
234        switch ( the_period->state ) {
235          case RATE_MONOTONIC_INACTIVE:
236            return_value = RTEMS_NOT_DEFINED;
237            break;
238          case RATE_MONOTONIC_EXPIRED:
[11c16a64]239          case RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING:
[5f9b3db]240            return_value = RTEMS_TIMEOUT;
241            break;
[ebe61382]242          case RATE_MONOTONIC_ACTIVE:
[5f9b3db]243          default:              /* unreached -- only to remove warnings */
[ebe61382]244            return_value = RTEMS_SUCCESSFUL;
[5f9b3db]245            break;
246        }
[2d2352b]247        _Objects_Put( &the_period->Object );
[5f9b3db]248        return( return_value );
249      }
250
251      _ISR_Disable( level );
[7eef54e]252      if ( the_period->state == RATE_MONOTONIC_INACTIVE ) {
253        _ISR_Enable( level );
[e1bce86]254
[ac9d2ecc]255        the_period->next_length = length;
256
[7eef54e]257        /*
258         *  Baseline statistics information for the beginning of a period.
259         */
260        _Rate_monotonic_Initiate_statistics( the_period );
[e1bce86]261
[7eef54e]262        the_period->state = RATE_MONOTONIC_ACTIVE;
263        _Watchdog_Initialize(
264          &the_period->Timer,
265          _Rate_monotonic_Timeout,
266          id,
267          NULL
268        );
[c3330a8]269
[7eef54e]270        _Watchdog_Insert_ticks( &the_period->Timer, length );
[2d2352b]271        _Objects_Put( &the_period->Object );
[7eef54e]272        return RTEMS_SUCCESSFUL;
273      }
[e1bce86]274
[7eef54e]275      if ( the_period->state == RATE_MONOTONIC_ACTIVE ) {
276        /*
277         *  Update statistics from the concluding period.
278         */
279        _Rate_monotonic_Update_statistics( the_period );
280
281        /*
282         *  This tells the _Rate_monotonic_Timeout that this task is
283         *  in the process of blocking on the period and that we
284         *  may be changing the length of the next period.
285         */
286        the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING;
287        the_period->next_length = length;
288
289        _ISR_Enable( level );
290
291        _Thread_Executing->Wait.id = the_period->Object.id;
292        _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
293
294        /*
295         *  Did the watchdog timer expire while we were actually blocking
296         *  on it?
297         */
298        _ISR_Disable( level );
299          local_state = the_period->state;
[5f9b3db]300          the_period->state = RATE_MONOTONIC_ACTIVE;
[7eef54e]301        _ISR_Enable( level );
302
303        /*
304         *  If it did, then we want to unblock ourself and continue as
305         *  if nothing happen.  The period was reset in the timeout routine.
306         */
307        if ( local_state == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING )
308          _Thread_Clear_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
309
[2d2352b]310        _Objects_Put( &the_period->Object );
[7eef54e]311        return RTEMS_SUCCESSFUL;
[5f9b3db]312      }
[ebe61382]313
[7eef54e]314      if ( the_period->state == RATE_MONOTONIC_EXPIRED ) {
[04323c98]315        /*
316         *  Update statistics from the concluding period
317         */
318        _Rate_monotonic_Update_statistics( the_period );
[7eef54e]319
[04323c98]320        _ISR_Enable( level );
[7eef54e]321
[04323c98]322        the_period->state = RATE_MONOTONIC_ACTIVE;
323        the_period->next_length = length;
[7eef54e]324
[04323c98]325        _Watchdog_Insert_ticks( &the_period->Timer, length );
[92635cb]326        _Scheduler_Release_job( the_period->owner, the_period->next_length );
[2d2352b]327        _Objects_Put( &the_period->Object );
[04323c98]328        return RTEMS_TIMEOUT;
[7eef54e]329      }
330
331      /*
332       *  These should never happen so just return invalid Id.
333       *    - RATE_MONOTONIC_OWNER_IS_BLOCKING:
334       *    - RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING:
335       */
[ebe61382]336#if defined(RTEMS_MULTIPROCESSING)
337    case OBJECTS_REMOTE:            /* should never return this */
338#endif
339    case OBJECTS_ERROR:
340      break;
[5f9b3db]341  }
342
[ebe61382]343  return RTEMS_INVALID_ID;
[5f9b3db]344}
Note: See TracBrowser for help on using the repository browser.