source: rtems/cpukit/rtems/src/ratemon.c @ 3235ad9

4.104.114.84.95
Last change on this file since 3235ad9 was 3235ad9, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 23, 1995 at 7:30:23 PM

Support for variable length names added to Object Handler. This supports
both fixed length "raw" names and strings from the API's point of view.

Both inline and macro implementations were tested.

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