source: rtems/cpukit/rtems/src/ratemon.c @ ac7d5ef0

4.104.114.84.95
Last change on this file since ac7d5ef0 was ac7d5ef0, checked in by Joel Sherrill <joel.sherrill@…>, on 05/11/95 at 17:39:37

Initial revision

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