source: rtems/cpukit/rtems/src/ratemon.c @ 7f6a24ab

4.104.114.84.95
Last change on this file since 7f6a24ab was 5250ff39, checked in by Joel Sherrill <joel.sherrill@…>, on 08/23/95 at 21:06:31

Moved _Thread_Information -> _RTEMS_tasks_Information.

Added a table of object information control blocks.

Modified _Thread_Get so it looks up a thread regardless of which
thread management "entity" (manager, internal, etc) actually "owns" it.

  • Property mode set to 100644
File size: 10.2 KB
Line 
1/*
2 *  Rate Monotonic Manager
3 *
4 *
5 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
6 *  On-Line Applications Research Corporation (OAR).
7 *  All rights assigned to U.S. Government, 1994.
8 *
9 *  This material may be reproduced by or for the U.S. Government pursuant
10 *  to the copyright license under the clause at DFARS 252.227-7013.  This
11 *  notice must appear in all copies of this file and its derivatives.
12 *
13 *  $Id$
14 */
15
16#include <rtems/system.h>
17#include <rtems/support.h>
18#include <rtems/isr.h>
19#include <rtems/object.h>
20#include <rtems/ratemon.h>
21#include <rtems/thread.h>
22
23/*PAGE
24 *
25 *  _Rate_monotonic_Manager_initialization
26 *
27 *  This routine initializes all Rate Monotonic Manager related
28 *  data structures.
29 *
30 *  Input parameters:
31 *    maximum_periods - number of periods timers to initialize
32 *
33 *  Output parameters:  NONE
34 *
35 *  NOTE: The Rate Monotonic Manager is built on top of the Watchdog
36 *        Handler.
37 */
38
39void _Rate_monotonic_Manager_initialization(
40  unsigned32 maximum_periods
41)
42{
43  _Objects_Initialize_information(
44    &_Rate_monotonic_Information,
45    OBJECTS_RTEMS_PERIODS,
46    FALSE,
47    maximum_periods,
48    sizeof( Rate_monotonic_Control ),
49    FALSE,
50    RTEMS_MAXIMUM_NAME_LENGTH,
51    FALSE
52  );
53}
54
55/*PAGE
56 *
57 *  rtems_rate_monotonic_create
58 *
59 *  This directive creates a rate monotonic timer and performs
60 *  some initialization.
61 *
62 *  Input parameters:
63 *    name - name of period
64 *    id   - pointer to rate monotonic id
65 *
66 *  Output parameters:
67 *    id                - rate monotonic id
68 *    RTEMS_SUCCESSFUL - if successful
69 *    error code        - if unsuccessful
70 */
71
72rtems_status_code rtems_rate_monotonic_create(
73  rtems_name    name,
74  Objects_Id   *id
75)
76{
77  Rate_monotonic_Control *the_period;
78
79  if ( !rtems_is_name_valid( name ) )
80    return( RTEMS_INVALID_NAME );
81
82  _Thread_Disable_dispatch();            /* to prevent deletion */
83
84  the_period = _Rate_monotonic_Allocate();
85
86  if ( !the_period ) {
87    _Thread_Enable_dispatch();
88    return( RTEMS_TOO_MANY );
89  }
90
91  the_period->owner = _Thread_Executing;
92  the_period->state = RATE_MONOTONIC_INACTIVE;
93
94  _Objects_Open( &_Rate_monotonic_Information, &the_period->Object, &name );
95
96  *id = the_period->Object.id;
97  _Thread_Enable_dispatch();
98  return( RTEMS_SUCCESSFUL );
99}
100
101/*PAGE
102 *
103 *  rtems_rate_monotonic_ident
104 *
105 *  This directive returns the system ID associated with
106 *  the rate monotonic period name.
107 *
108 *  Input parameters:
109 *    name - user defined period name
110 *    id   - pointer to period id
111 *
112 *  Output parameters:
113 *    *id               - region id
114 *    RTEMS_SUCCESSFUL - if successful
115 *    error code        - if unsuccessful
116 */
117
118rtems_status_code rtems_rate_monotonic_ident(
119  rtems_name    name,
120  Objects_Id   *id
121)
122{
123  return _Objects_Name_to_id(
124    &_Rate_monotonic_Information,
125    &name,
126    RTEMS_SEARCH_LOCAL_NODE,
127    id
128  );
129}
130
131/*PAGE
132 *
133 *  rtems_rate_monotonic_cancel
134 *
135 *  This directive allows a thread to cancel a rate monotonic timer.
136 *
137 *  Input parameters:
138 *    id - rate monotonic id
139 *
140 *  Output parameters:
141 *    RTEMS_SUCCESSFUL - if successful and caller is not the owning thread
142 *    error code        - if unsuccessful
143 */
144
145rtems_status_code rtems_rate_monotonic_cancel(
146  Objects_Id id
147)
148{
149  Rate_monotonic_Control *the_period;
150  Objects_Locations              location;
151
152  the_period = _Rate_monotonic_Get( id, &location );
153  switch ( location ) {
154    case OBJECTS_ERROR:
155      return( RTEMS_INVALID_ID );
156    case OBJECTS_REMOTE:            /* should never return this */
157      return( RTEMS_INTERNAL_ERROR );
158    case OBJECTS_LOCAL:
159      if ( !_Thread_Is_executing( the_period->owner ) ) {
160        _Thread_Enable_dispatch();
161        return( RTEMS_NOT_OWNER_OF_RESOURCE );
162      }
163      (void) _Watchdog_Remove( &the_period->Timer );
164      the_period->state = RATE_MONOTONIC_INACTIVE;
165      _Thread_Enable_dispatch();
166      return( RTEMS_SUCCESSFUL );
167  }
168
169  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
170}
171
172/*PAGE
173 *
174 *  rtems_rate_monotonic_delete
175 *
176 *  This directive allows a thread to delete a rate monotonic timer.
177 *
178 *  Input parameters:
179 *    id - rate monotonic id
180 *
181 *  Output parameters:
182 *    RTEMS_SUCCESSFUL - if successful
183 *    error code        - if unsuccessful
184 */
185
186rtems_status_code rtems_rate_monotonic_delete(
187  Objects_Id id
188)
189{
190  Rate_monotonic_Control *the_period;
191  Objects_Locations              location;
192
193  the_period = _Rate_monotonic_Get( id, &location );
194  switch ( location ) {
195    case OBJECTS_ERROR:
196      return( RTEMS_INVALID_ID );
197    case OBJECTS_REMOTE:            /* should never return this */
198      return( RTEMS_INTERNAL_ERROR );
199    case OBJECTS_LOCAL:
200      _Objects_Close( &_Rate_monotonic_Information, &the_period->Object );
201      (void) _Watchdog_Remove( &the_period->Timer );
202      the_period->state = RATE_MONOTONIC_INACTIVE;
203      _Rate_monotonic_Free( the_period );
204      _Thread_Enable_dispatch();
205      return( RTEMS_SUCCESSFUL );
206  }
207
208  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
209}
210
211/*PAGE
212 *
213 *  rtems_rate_monotonic_period
214 *
215 *  This directive allows a thread to manipulate a rate monotonic timer.
216 *
217 *  Input parameters:
218 *    id     - rate monotonic id
219 *    length - length of period (in ticks)
220 *
221 *  Output parameters:
222 *    RTEMS_SUCCESSFUL - if successful
223 *    error code        - if unsuccessful
224 */
225
226rtems_status_code rtems_rate_monotonic_period(
227  Objects_Id        id,
228  rtems_interval length
229)
230{
231  Rate_monotonic_Control *the_period;
232  Objects_Locations       location;
233  rtems_status_code            return_value;
234
235  the_period = _Rate_monotonic_Get( id, &location );
236  switch ( location ) {
237    case OBJECTS_ERROR:
238      return( RTEMS_INVALID_ID );
239    case OBJECTS_REMOTE:            /* should never return this */
240      return( RTEMS_INTERNAL_ERROR );
241    case OBJECTS_LOCAL:
242      if ( !_Thread_Is_executing( the_period->owner ) ) {
243        _Thread_Enable_dispatch();
244        return( RTEMS_NOT_OWNER_OF_RESOURCE );
245      }
246
247      if ( length == RTEMS_PERIOD_STATUS ) {
248        switch ( the_period->state ) {
249          case RATE_MONOTONIC_INACTIVE:
250            return_value = RTEMS_NOT_DEFINED;
251            break;
252          case RATE_MONOTONIC_ACTIVE:
253            return_value = RTEMS_SUCCESSFUL;
254            break;
255          case RATE_MONOTONIC_EXPIRED:
256            return_value = RTEMS_TIMEOUT;
257            break;
258          default:              /* unreached -- only to remove warnings */
259            return_value = RTEMS_INTERNAL_ERROR;
260            break;
261        }
262        _Thread_Enable_dispatch();
263        return( return_value );
264      }
265
266      switch ( the_period->state ) {
267        case RATE_MONOTONIC_INACTIVE:
268          the_period->state = RATE_MONOTONIC_ACTIVE;
269          _Watchdog_Initialize(
270            &the_period->Timer,
271            _Rate_monotonic_Timeout,
272            id,
273            NULL
274          );
275          _Watchdog_Insert_ticks(
276                     &the_period->Timer, length, WATCHDOG_ACTIVATE_NOW );
277          _Thread_Enable_dispatch();
278          return( RTEMS_SUCCESSFUL );
279
280        case RATE_MONOTONIC_ACTIVE:
281/* following is and could be a critical section problem */
282          _Thread_Executing->Wait.id  = the_period->Object.id;
283          if ( _Rate_monotonic_Set_state( the_period ) ) {
284            _Thread_Enable_dispatch();
285            return( RTEMS_SUCCESSFUL );
286          }
287         /* has expired -- fall into next case */
288        case RATE_MONOTONIC_EXPIRED:
289          the_period->state = RATE_MONOTONIC_ACTIVE;
290          _Watchdog_Insert_ticks(
291                     &the_period->Timer, length, WATCHDOG_ACTIVATE_NOW );
292          _Thread_Enable_dispatch();
293          return( RTEMS_TIMEOUT );
294      }
295  }
296
297  return( RTEMS_INTERNAL_ERROR );   /* unreached - only to remove warnings */
298}
299
300/*PAGE
301 *
302 * _Rate_monotonic_Set_state
303 *
304 * This kernel routine sets the STATES_WAITING_FOR_PERIOD state in
305 * the running thread's tcb if the specified period has not expired.
306 * The ready chain is adjusted if necessary.
307 *
308 * Input parameters:
309 *   the_period - pointer to period control block
310 *
311 * Output parameters:
312 *   TRUE  - if blocked successfully for period
313 *   FALSE - if period has expired
314 *
315 *  INTERRUPT LATENCY:
316 *    delete node
317 *    priority map
318 *    select heir
319 */
320
321boolean _Rate_monotonic_Set_state(
322Rate_monotonic_Control *the_period
323)
324{
325  Thread_Control *executing;
326  Chain_Control  *ready;
327  ISR_Level              level;
328  States_Control         old_state;
329
330  executing = _Thread_Executing;
331  ready     = executing->ready;
332  _ISR_Disable( level );
333
334  old_state = executing->current_state;
335
336  if ( _Rate_monotonic_Is_expired( the_period ) ) {
337    _ISR_Enable( level );
338    return( FALSE );
339  }
340
341  executing->current_state =
342             _States_Set( STATES_WAITING_FOR_PERIOD, old_state );
343
344  if ( _States_Is_ready( old_state ) ) {
345    if ( _Chain_Has_only_one_node( ready ) ) {
346      _Chain_Initialize_empty( ready );
347      _Priority_Remove_from_bit_map( &executing->Priority_map );
348      _ISR_Flash( level );
349    } else {
350      _Chain_Extract_unprotected( &executing->Object.Node );
351      _ISR_Flash( level );
352    }
353
354    if ( _Thread_Is_heir( executing ) )
355      _Thread_Calculate_heir();
356
357    _Context_Switch_necessary = TRUE;
358  }
359
360  _ISR_Enable( level );
361  return( TRUE );
362}
363
364/*PAGE
365 *
366 *  _Rate_monotonic_Timeout
367 *
368 *  This routine processes a period ending.  If the owning thread
369 *  is waiting for the period, that thread is unblocked and the
370 *  period reinitiated.  Otherwise, the period is expired.
371 *  This routine is called by the watchdog handler.
372 *
373 *  Input parameters:
374 *    id - period id
375 *
376 *  Output parameters: NONE
377 */
378
379void _Rate_monotonic_Timeout(
380  Objects_Id  id,
381  void       *ignored
382)
383{
384  Rate_monotonic_Control *the_period;
385  Objects_Locations              location;
386  Thread_Control         *the_thread;
387
388  the_period = _Rate_monotonic_Get( id, &location );
389  switch ( location ) {
390    case OBJECTS_ERROR:
391    case OBJECTS_REMOTE:  /* impossible */
392      break;
393    case OBJECTS_LOCAL:
394      the_thread = the_period->owner;
395      if ( _States_Is_waiting_for_period( the_thread->current_state ) &&
396            the_thread->Wait.id == the_period->Object.id ) {
397        _Thread_Unblock( the_thread );
398        _Watchdog_Reset( &the_period->Timer );
399      }
400      else
401        the_period->state = RATE_MONOTONIC_EXPIRED;
402      _Thread_Unnest_dispatch();
403      break;
404  }
405}
406
Note: See TracBrowser for help on using the repository browser.