source: rtems/cpukit/rtems/src/ratemonperiod.c @ 0e87deaa

4.104.114.95
Last change on this file since 0e87deaa was 0e87deaa, checked in by Joel Sherrill <joel.sherrill@…>, on 10/26/07 at 20:19:02

2007-10-26 Joel Sherrill <joel.sherrill@…>

  • itron/src/can_wup.c, itron/src/chg_pri.c, itron/src/del_mbf.c, itron/src/del_mbx.c, itron/src/del_sem.c, itron/src/del_tsk.c, itron/src/frsm_tsk.c, itron/src/ref_mbf.c, itron/src/ref_mbx.c, itron/src/ref_sem.c, itron/src/ref_tsk.c, itron/src/rel_wai.c, itron/src/rsm_tsk.c, itron/src/sig_sem.c, itron/src/snd_mbx.c, itron/src/sta_tsk.c, itron/src/sus_tsk.c, itron/src/ter_tsk.c, itron/src/trcv_mbf.c, itron/src/trcv_mbx.c, itron/src/tsnd_mbf.c, itron/src/twai_sem.c, posix/src/cancel.c, posix/src/conddestroy.c, posix/src/condinit.c, posix/src/condsignalsupp.c, posix/src/condwaitsupp.c, posix/src/keydelete.c, posix/src/keygetspecific.c, posix/src/keysetspecific.c, posix/src/mqueueclose.c, posix/src/mqueuegetattr.c, posix/src/mqueuenotify.c, posix/src/mqueuerecvsupp.c, posix/src/mqueuesendsupp.c, posix/src/mqueuesetattr.c, posix/src/mutexdestroy.c, posix/src/mutexgetprioceiling.c, posix/src/mutexinit.c, posix/src/mutexlocksupp.c, posix/src/mutexsetprioceiling.c, posix/src/mutexunlock.c, posix/src/pbarrierdestroy.c, posix/src/pbarrierwait.c, posix/src/prwlockdestroy.c, posix/src/prwlockrdlock.c, posix/src/prwlocktimedrdlock.c, posix/src/prwlocktimedwrlock.c, posix/src/prwlocktryrdlock.c, posix/src/prwlocktrywrlock.c, posix/src/prwlockunlock.c, posix/src/prwlockwrlock.c, posix/src/pspindestroy.c, posix/src/pspinlock.c, posix/src/pspintrylock.c, posix/src/pspinunlock.c, posix/src/pthreaddetach.c, posix/src/pthreadequal.c, posix/src/pthreadgetschedparam.c, posix/src/pthreadjoin.c, posix/src/pthreadkill.c, posix/src/pthreadsetschedparam.c, posix/src/ptimer1.c, posix/src/semaphorewaitsupp.c, posix/src/semclose.c, posix/src/semdestroy.c, posix/src/semgetvalue.c, posix/src/sempost.c, posix/src/types.c, rtems/src/barrierdelete.c, rtems/src/barrierrelease.c, rtems/src/barrierwait.c, rtems/src/dpmemdelete.c, rtems/src/dpmemexternal2internal.c, rtems/src/dpmeminternal2external.c, rtems/src/eventsend.c, rtems/src/eventtimeout.c, rtems/src/msgqbroadcast.c, rtems/src/msgqdelete.c, rtems/src/msgqflush.c, rtems/src/msgqgetnumberpending.c, rtems/src/msgqreceive.c, rtems/src/msgqsend.c, rtems/src/msgqurgent.c, rtems/src/partdelete.c, rtems/src/partgetbuffer.c, rtems/src/partreturnbuffer.c, rtems/src/ratemoncancel.c, rtems/src/ratemondelete.c, rtems/src/ratemongetstatistics.c, rtems/src/ratemongetstatus.c, rtems/src/ratemonperiod.c, rtems/src/ratemonresetstatistics.c, rtems/src/ratemontimeout.c, rtems/src/regiondelete.c, rtems/src/regionextend.c, rtems/src/regiongetfreeinfo.c, rtems/src/regiongetinfo.c, rtems/src/regiongetsegment.c, rtems/src/regiongetsegmentsize.c, rtems/src/regionresizesegment.c, rtems/src/regionreturnsegment.c, rtems/src/semdelete.c, rtems/src/semflush.c, rtems/src/semobtain.c, rtems/src/semrelease.c, rtems/src/signalsend.c, rtems/src/taskdelete.c, rtems/src/taskgetnote.c, rtems/src/taskissuspended.c, rtems/src/taskrestart.c, rtems/src/taskresume.c, rtems/src/tasksetnote.c, rtems/src/tasksetpriority.c, rtems/src/taskstart.c, rtems/src/tasksuspend.c, rtems/src/taskvariableadd.c, rtems/src/taskvariabledelete.c, rtems/src/taskvariableget.c, rtems/src/timercancel.c, rtems/src/timerdelete.c, rtems/src/timerfireafter.c, rtems/src/timerfirewhen.c, rtems/src/timergetinfo.c, rtems/src/timerreset.c, rtems/src/timerserverfireafter.c, rtems/src/timerserverfirewhen.c, sapi/src/extensiondelete.c, score/include/rtems/score/object.h, score/src/corerwlocktimeout.c, score/src/mpci.c, score/src/objectgetnameasstring.c, score/src/threaddelayended.c, score/src/threadqtimeout.c: When multiprocessing is disabled, do not even allow the constant OBJECTS_REMOTE to appear in the source. Even at -O2, the presence of a case OBJECTS_REMOTE in each id->pointer _Objects_Get switch results in the generation of binary code which can NOT be reached.
  • Property mode set to 100644
File size: 10.5 KB
Line 
1/*
2 *  Rate Monotonic Manager - Period Blocking and Status
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#if HAVE_CONFIG_H
15#include "config.h"
16#endif
17
18#include <rtems/system.h>
19#include <rtems/rtems/status.h>
20#include <rtems/rtems/support.h>
21#include <rtems/score/isr.h>
22#include <rtems/score/object.h>
23#include <rtems/rtems/ratemon.h>
24#include <rtems/score/thread.h>
25#if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \
26    defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
27  #include <rtems/score/timespec.h>
28  extern struct timespec _Thread_Time_of_last_context_switch;
29#endif
30
31void _Rate_monotonic_Update_statistics(
32  Rate_monotonic_Control    *the_period
33)
34{
35  rtems_rate_monotonic_period_statistics *stats;
36  #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
37    struct timespec                       executed;
38  #else
39    uint32_t                              ticks_executed_since_last_period;
40  #endif
41  #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS
42    struct timespec                       period_start;
43    struct timespec                       since_last_period;
44  #else
45    uint32_t                              ticks_since_last_period;
46  #endif
47  #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \
48      defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
49    struct timespec  uptime;
50
51    /*
52     * Obtain the current time since boot
53     */
54    _TOD_Get_uptime( &uptime );
55  #endif
56
57  /*
58   *  Assume we are only called in states where it is appropriate
59   *  to update the statistics.  This should only be RATE_MONOTONIC_ACTIVE
60   *  and RATE_MONOTONIC_EXPIRED.
61   */
62
63  /*
64   *  Grab basic information
65   */
66
67  #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS
68    period_start               = the_period->time_at_period;
69    _Timespec_Subtract( &period_start, &uptime, &since_last_period );
70    the_period->time_at_period = uptime;
71  #else
72    ticks_since_last_period =
73        _Watchdog_Ticks_since_boot - the_period->time_at_period;
74    the_period->time_at_period = _Watchdog_Ticks_since_boot;
75  #endif
76
77  #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
78    {
79      struct timespec ran, used;
80       
81      /* Grab CPU usage when the thread got switched in */
82      used = _Thread_Executing->cpu_time_used;
83
84      /* How much time time since last context switch */
85      _Timespec_Subtract(&_Thread_Time_of_last_context_switch, &uptime, &ran);
86
87      /* executed += ran */
88      _Timespec_Add_to( &used, &ran );
89
90       /* executed = current cpu usage - value at start of period */
91      _Timespec_Subtract(
92         &the_period->owner_executed_at_period,
93         &used,
94         &executed
95      );
96    }
97  #else
98      ticks_executed_since_last_period = the_period->owner->ticks_executed -
99        the_period->owner_ticks_executed_at_period;
100  #endif
101
102  /*
103   *  Now update the statistics
104   */
105
106  stats = &the_period->Statistics;
107  stats->count++;
108
109
110  if ( the_period->state == RATE_MONOTONIC_EXPIRED )
111    stats->missed_count++;
112
113  /*
114   *  Update CPU time
115   */
116
117  #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
118    _Timespec_Add_to( &stats->total_cpu_time, &executed );
119
120    if ( _Timespec_Less_than( &executed, &stats->min_cpu_time ) )
121      stats->min_cpu_time = executed;
122
123    if ( _Timespec_Greater_than( &executed, &stats->max_cpu_time ) )
124      stats->max_cpu_time = executed;
125  #else
126    stats->total_cpu_time  += ticks_executed_since_last_period;
127
128    if ( ticks_executed_since_last_period < stats->min_cpu_time )
129      stats->min_cpu_time = ticks_executed_since_last_period;
130
131    if ( ticks_executed_since_last_period > stats->max_cpu_time )
132      stats->max_cpu_time = ticks_executed_since_last_period;
133  #endif
134
135  /*
136   *  Update Wall time
137   */
138
139  #ifndef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS
140    stats->total_wall_time += ticks_since_last_period;
141
142    if ( ticks_since_last_period < stats->min_wall_time )
143      stats->min_wall_time = ticks_since_last_period;
144
145    if ( ticks_since_last_period > stats->max_wall_time )
146      stats->max_wall_time = ticks_since_last_period;
147  #else
148    _Timespec_Add_to( &stats->total_wall_time, &since_last_period );
149
150    if ( _Timespec_Less_than( &since_last_period, &stats->min_wall_time ) )
151      stats->min_wall_time = since_last_period;
152
153    if ( _Timespec_Greater_than( &since_last_period, &stats->max_wall_time ) )
154      stats->max_wall_time = since_last_period;
155  #endif
156}
157
158
159/*PAGE
160 *
161 *  rtems_rate_monotonic_period
162 *
163 *  This directive allows a thread to manipulate a rate monotonic timer.
164 *
165 *  Input parameters:
166 *    id     - rate monotonic id
167 *    length - length of period (in ticks)
168 *
169 *  Output parameters:
170 *    RTEMS_SUCCESSFUL - if successful
171 *    error code       - if unsuccessful
172 */
173
174rtems_status_code rtems_rate_monotonic_period(
175  Objects_Id        id,
176  rtems_interval    length
177)
178{
179  Rate_monotonic_Control              *the_period;
180  Objects_Locations                    location;
181  rtems_status_code                    return_value;
182  rtems_rate_monotonic_period_states   local_state;
183  ISR_Level                            level;
184
185  the_period = _Rate_monotonic_Get( id, &location );
186  switch ( location ) {
187#if defined(RTEMS_MULTIPROCESSING)
188    case OBJECTS_REMOTE:            /* should never return this */
189      return RTEMS_INTERNAL_ERROR;
190#endif
191
192    case OBJECTS_ERROR:
193      return RTEMS_INVALID_ID;
194
195    case OBJECTS_LOCAL:
196      if ( !_Thread_Is_executing( the_period->owner ) ) {
197        _Thread_Enable_dispatch();
198        return RTEMS_NOT_OWNER_OF_RESOURCE;
199      }
200
201      if ( length == RTEMS_PERIOD_STATUS ) {
202        switch ( the_period->state ) {
203          case RATE_MONOTONIC_INACTIVE:
204            return_value = RTEMS_NOT_DEFINED;
205            break;
206          case RATE_MONOTONIC_ACTIVE:
207            return_value = RTEMS_SUCCESSFUL;
208            break;
209          case RATE_MONOTONIC_EXPIRED:
210            return_value = RTEMS_TIMEOUT;
211            break;
212          default:              /* unreached -- only to remove warnings */
213            return_value = RTEMS_INTERNAL_ERROR;
214            break;
215        }
216        _Thread_Enable_dispatch();
217        return( return_value );
218      }
219
220      _ISR_Disable( level );
221      switch ( the_period->state ) {
222        case RATE_MONOTONIC_INACTIVE: {
223          #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \
224              defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
225            struct timespec uptime;
226          #endif
227
228          /*
229           *  No need to update statistics -- there are not a period active
230           */
231
232          _ISR_Enable( level );
233
234
235          #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \
236              defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
237            _TOD_Get_uptime( &uptime );
238          #endif
239             
240          #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS
241            /*
242             * Since the statistics didn't update the starting time,
243             * we do it here.
244             */
245            the_period->time_at_period = uptime;
246          #else
247            the_period->time_at_period = _Watchdog_Ticks_since_boot;
248          #endif
249
250          #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
251            {
252              struct timespec ran;
253
254              the_period->owner_executed_at_period =
255                _Thread_Executing->cpu_time_used;
256
257              /* How much time time since last context switch */
258              _Timespec_Subtract(
259                &_Thread_Time_of_last_context_switch,
260                &uptime,
261                &ran
262              );
263
264              /* The thread had executed before the last context switch also.
265               *   
266               *     the_period->owner_executed_at_period += ran
267               */
268              _Timespec_Add_to( &the_period->owner_executed_at_period, &ran );
269            }
270          #else
271            the_period->owner_ticks_executed_at_period =
272              _Thread_Executing->ticks_executed;
273          #endif
274
275          the_period->state = RATE_MONOTONIC_ACTIVE;
276          _Watchdog_Initialize(
277            &the_period->Timer,
278            _Rate_monotonic_Timeout,
279            id,
280            NULL
281          );
282
283          the_period->next_length = length;
284
285          _Watchdog_Insert_ticks( &the_period->Timer, length );
286          _Thread_Enable_dispatch();
287          return RTEMS_SUCCESSFUL;
288        }
289        case RATE_MONOTONIC_ACTIVE:
290
291          /*
292           *  Update statistics from the concluding period
293           */
294          _Rate_monotonic_Update_statistics( the_period );
295
296          /*
297           *  This tells the _Rate_monotonic_Timeout that this task is
298           *  in the process of blocking on the period and that we
299           *  may be changing the length of the next period.
300           */
301
302          the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING;
303          the_period->next_length = length;
304
305          _ISR_Enable( level );
306
307          _Thread_Executing->Wait.id = the_period->Object.id;
308          _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
309
310          /*
311           *  Did the watchdog timer expire while we were actually blocking
312           *  on it?
313           */
314
315          _ISR_Disable( level );
316            local_state = the_period->state;
317            the_period->state = RATE_MONOTONIC_ACTIVE;
318          _ISR_Enable( level );
319
320          /*
321           *  If it did, then we want to unblock ourself and continue as
322           *  if nothing happen.  The period was reset in the timeout routine.
323           */
324
325          if ( local_state == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING )
326            _Thread_Clear_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
327
328          _Thread_Enable_dispatch();
329          return RTEMS_SUCCESSFUL;
330          break;
331
332        case RATE_MONOTONIC_EXPIRED:
333          /*
334           *  Update statistics from the concluding period
335           */
336          _Rate_monotonic_Update_statistics( the_period );
337
338          _ISR_Enable( level );
339
340          the_period->state = RATE_MONOTONIC_ACTIVE;
341          the_period->next_length = length;
342
343          _Watchdog_Insert_ticks( &the_period->Timer, length );
344          _Thread_Enable_dispatch();
345          return RTEMS_TIMEOUT;
346
347        case RATE_MONOTONIC_OWNER_IS_BLOCKING:
348        case RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING:
349          /*
350           *  These should never happen.
351           */
352          break;
353      }
354  }
355
356  return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
357}
Note: See TracBrowser for help on using the repository browser.