Changeset 5f9b3db in rtems


Ignore:
Timestamp:
May 17, 1999, 11:03:07 PM (22 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
cc2bc302
Parents:
c06d8f64
Message:

Split Rate Monotonic Manager into one routine per file.

Files:
14 added
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/exec/rtems/src/Makefile.in

    rc06d8f64 r5f9b3db  
    4141  semtranslatereturncode
    4242
     43RATEMON_PIECES=\
     44  ratemon ratemoncancel ratemoncreate ratemondelete ratemongetstatus \
     45  ratemonident ratemonperiod ratemontimeout
     46
    4347C_PIECES=attr $(CLOCK_PIECES) dpmem event intr intrbody \
    4448   $(MESSAGE_QUEUE_PIECES) \
    45    part ratemon $(REGION_PIECES) $(SEMAPHORE_PIECES) signal \
     49   part $(RATEMON_PIECES) $(REGION_PIECES) $(SEMAPHORE_PIECES) signal \
    4650   $(TASK_PIECES) timer $(MP_PIECES)
    4751C_FILES=$(C_PIECES:%=%.c)
  • c/src/exec/rtems/src/ratemon.c

    rc06d8f64 r5f9b3db  
    5353  );
    5454}
    55 
    56 /*PAGE
    57  *
    58  *  rtems_rate_monotonic_create
    59  *
    60  *  This directive creates a rate monotonic timer and performs
    61  *  some initialization.
    62  *
    63  *  Input parameters:
    64  *    name - name of period
    65  *    id   - pointer to rate monotonic id
    66  *
    67  *  Output parameters:
    68  *    id                - rate monotonic id
    69  *    RTEMS_SUCCESSFUL - if successful
    70  *    error code        - if unsuccessful
    71  */
    72 
    73 rtems_status_code rtems_rate_monotonic_create(
    74   rtems_name    name,
    75   Objects_Id   *id
    76 )
    77 {
    78   Rate_monotonic_Control *the_period;
    79 
    80   if ( !rtems_is_name_valid( name ) )
    81     return RTEMS_INVALID_NAME;
    82 
    83   _Thread_Disable_dispatch();            /* to prevent deletion */
    84 
    85   the_period = _Rate_monotonic_Allocate();
    86 
    87   if ( !the_period ) {
    88     _Thread_Enable_dispatch();
    89     return RTEMS_TOO_MANY;
    90   }
    91 
    92   the_period->owner = _Thread_Executing;
    93   the_period->state = RATE_MONOTONIC_INACTIVE;
    94 
    95   _Objects_Open( &_Rate_monotonic_Information, &the_period->Object, &name );
    96 
    97   *id = the_period->Object.id;
    98   _Thread_Enable_dispatch();
    99   return RTEMS_SUCCESSFUL;
    100 }
    101 
    102 /*PAGE
    103  *
    104  *  rtems_rate_monotonic_ident
    105  *
    106  *  This directive returns the system ID associated with
    107  *  the rate monotonic period name.
    108  *
    109  *  Input parameters:
    110  *    name - user defined period name
    111  *    id   - pointer to period id
    112  *
    113  *  Output parameters:
    114  *    *id               - region id
    115  *    RTEMS_SUCCESSFUL - if successful
    116  *    error code        - if unsuccessful
    117  */
    118 
    119 rtems_status_code rtems_rate_monotonic_ident(
    120   rtems_name    name,
    121   Objects_Id   *id
    122 )
    123 {
    124   Objects_Name_to_id_errors  status;
    125 
    126   status = _Objects_Name_to_id(
    127     &_Rate_monotonic_Information,
    128     &name,
    129     OBJECTS_SEARCH_LOCAL_NODE,
    130     id
    131   );
    132 
    133   return _Status_Object_name_errors_to_status[ status ];
    134 }
    135 
    136 /*PAGE
    137  *
    138  *  rtems_rate_monotonic_cancel
    139  *
    140  *  This directive allows a thread to cancel a rate monotonic timer.
    141  *
    142  *  Input parameters:
    143  *    id - rate monotonic id
    144  *
    145  *  Output parameters:
    146  *    RTEMS_SUCCESSFUL - if successful and caller is not the owning thread
    147  *    error code        - if unsuccessful
    148  */
    149 
    150 rtems_status_code rtems_rate_monotonic_cancel(
    151   Objects_Id id
    152 )
    153 {
    154   Rate_monotonic_Control *the_period;
    155   Objects_Locations              location;
    156 
    157   the_period = _Rate_monotonic_Get( id, &location );
    158   switch ( location ) {
    159     case OBJECTS_REMOTE:           
    160       return RTEMS_INTERNAL_ERROR;  /* should never return this */
    161 
    162     case OBJECTS_ERROR:
    163       return RTEMS_INVALID_ID;
    164 
    165     case OBJECTS_LOCAL:
    166       if ( !_Thread_Is_executing( the_period->owner ) ) {
    167         _Thread_Enable_dispatch();
    168         return RTEMS_NOT_OWNER_OF_RESOURCE;
    169       }
    170       (void) _Watchdog_Remove( &the_period->Timer );
    171       the_period->state = RATE_MONOTONIC_INACTIVE;
    172       _Thread_Enable_dispatch();
    173       return RTEMS_SUCCESSFUL;
    174   }
    175 
    176   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    177 }
    178 
    179 /*PAGE
    180  *
    181  *  rtems_rate_monotonic_delete
    182  *
    183  *  This directive allows a thread to delete a rate monotonic timer.
    184  *
    185  *  Input parameters:
    186  *    id - rate monotonic id
    187  *
    188  *  Output parameters:
    189  *    RTEMS_SUCCESSFUL - if successful
    190  *    error code        - if unsuccessful
    191  */
    192 
    193 rtems_status_code rtems_rate_monotonic_delete(
    194   Objects_Id id
    195 )
    196 {
    197   Rate_monotonic_Control *the_period;
    198   Objects_Locations              location;
    199 
    200   the_period = _Rate_monotonic_Get( id, &location );
    201   switch ( location ) {
    202     case OBJECTS_REMOTE:            /* should never return this */
    203       return RTEMS_INTERNAL_ERROR;
    204 
    205     case OBJECTS_ERROR:
    206       return RTEMS_INVALID_ID;
    207 
    208     case OBJECTS_LOCAL:
    209       _Objects_Close( &_Rate_monotonic_Information, &the_period->Object );
    210       (void) _Watchdog_Remove( &the_period->Timer );
    211       the_period->state = RATE_MONOTONIC_INACTIVE;
    212       _Rate_monotonic_Free( the_period );
    213       _Thread_Enable_dispatch();
    214       return RTEMS_SUCCESSFUL;
    215   }
    216 
    217   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    218 }
    219 
    220 /*PAGE
    221  *
    222  *  rtems_rate_monotonic_get_status
    223  *
    224  *  This directive allows a thread to obtain status information on a
    225  *  period.
    226  *
    227  *  Input parameters:
    228  *    id     - rate monotonic id
    229  *    status - pointer to status control block
    230  *
    231  *  Output parameters:
    232  *    RTEMS_SUCCESSFUL - if successful
    233  *    error code        - if unsuccessful
    234  *
    235  */
    236 
    237 rtems_status_code rtems_rate_monotonic_get_status(
    238   Objects_Id                           id,
    239   rtems_rate_monotonic_period_status  *status
    240 )
    241 {
    242   Objects_Locations              location;
    243   Rate_monotonic_Control        *the_period;
    244 
    245   if ( status == NULL )
    246     return RTEMS_INVALID_ADDRESS;
    247 
    248   the_period = _Rate_monotonic_Get( id, &location );
    249   switch ( location ) {
    250     case OBJECTS_REMOTE:            /* should never return this */
    251       return RTEMS_INTERNAL_ERROR;
    252 
    253     case OBJECTS_ERROR:
    254       return RTEMS_INVALID_ID;
    255 
    256     case OBJECTS_LOCAL:
    257       status->state = the_period->state;
    258 
    259       if ( status->state == RATE_MONOTONIC_INACTIVE ) {
    260         status->ticks_since_last_period = 0;
    261         status->ticks_executed_since_last_period = 0;
    262       } else {
    263         status->ticks_since_last_period =
    264           _Watchdog_Ticks_since_boot - the_period->time_at_period;
    265 
    266         status->ticks_executed_since_last_period =
    267           the_period->owner->ticks_executed -
    268             the_period->owner_ticks_executed_at_period;
    269       }
    270 
    271       _Thread_Enable_dispatch();
    272       return RTEMS_SUCCESSFUL;
    273   }
    274 
    275   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    276 }
    277 
    278 
    279 /*PAGE
    280  *
    281  *  rtems_rate_monotonic_period
    282  *
    283  *  This directive allows a thread to manipulate a rate monotonic timer.
    284  *
    285  *  Input parameters:
    286  *    id     - rate monotonic id
    287  *    length - length of period (in ticks)
    288  *
    289  *  Output parameters:
    290  *    RTEMS_SUCCESSFUL - if successful
    291  *    error code        - if unsuccessful
    292  */
    293 
    294 rtems_status_code rtems_rate_monotonic_period(
    295   Objects_Id        id,
    296   rtems_interval    length
    297 )
    298 {
    299   Rate_monotonic_Control              *the_period;
    300   Objects_Locations                    location;
    301   rtems_status_code                    return_value;
    302   rtems_rate_monotonic_period_states   local_state;
    303   ISR_Level                            level;
    304 
    305   the_period = _Rate_monotonic_Get( id, &location );
    306   switch ( location ) {
    307     case OBJECTS_REMOTE:            /* should never return this */
    308       return RTEMS_INTERNAL_ERROR;
    309 
    310     case OBJECTS_ERROR:
    311       return RTEMS_INVALID_ID;
    312 
    313     case OBJECTS_LOCAL:
    314       if ( !_Thread_Is_executing( the_period->owner ) ) {
    315         _Thread_Enable_dispatch();
    316         return RTEMS_NOT_OWNER_OF_RESOURCE;
    317       }
    318 
    319       if ( length == RTEMS_PERIOD_STATUS ) {
    320         switch ( the_period->state ) {
    321           case RATE_MONOTONIC_INACTIVE:
    322             return_value = RTEMS_NOT_DEFINED;
    323             break;
    324           case RATE_MONOTONIC_ACTIVE:
    325             return_value = RTEMS_SUCCESSFUL;
    326             break;
    327           case RATE_MONOTONIC_EXPIRED:
    328             return_value = RTEMS_TIMEOUT;
    329             break;
    330           default:              /* unreached -- only to remove warnings */
    331             return_value = RTEMS_INTERNAL_ERROR;
    332             break;
    333         }
    334         _Thread_Enable_dispatch();
    335         return( return_value );
    336       }
    337 
    338       _ISR_Disable( level );
    339       switch ( the_period->state ) {
    340         case RATE_MONOTONIC_INACTIVE:
    341           _ISR_Enable( level );
    342           the_period->state = RATE_MONOTONIC_ACTIVE;
    343           _Watchdog_Initialize(
    344             &the_period->Timer,
    345             _Rate_monotonic_Timeout,
    346             id,
    347             NULL
    348           );
    349 
    350           the_period->owner_ticks_executed_at_period =
    351             _Thread_Executing->ticks_executed;
    352 
    353           the_period->time_at_period = _Watchdog_Ticks_since_boot;
    354 
    355           _Watchdog_Insert_ticks( &the_period->Timer, length );
    356           _Thread_Enable_dispatch();
    357           return RTEMS_SUCCESSFUL;
    358 
    359         case RATE_MONOTONIC_ACTIVE:
    360           /*
    361            *  This tells the _Rate_monotonic_Timeout that this task is
    362            *  in the process of blocking on the period.
    363            */
    364 
    365           the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING;
    366           _ISR_Enable( level );
    367 
    368           _Thread_Executing->Wait.id = the_period->Object.id;
    369           _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
    370          
    371           /*
    372            *  Did the watchdog timer expire while we were actually blocking
    373            *  on it?
    374            */
    375 
    376           _ISR_Disable( level );
    377             local_state = the_period->state;
    378             the_period->state = RATE_MONOTONIC_ACTIVE;
    379           _ISR_Enable( level );
    380 
    381           /*
    382            *  If it did, then we want to unblock ourself and continue as
    383            *  if nothing happen.  The period was reset in the timeout routine.
    384            */
    385 
    386           if ( local_state == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING )
    387             _Thread_Clear_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
    388 
    389           _Thread_Enable_dispatch();
    390           return RTEMS_SUCCESSFUL;
    391           break;
    392 
    393         case RATE_MONOTONIC_EXPIRED:
    394           _ISR_Enable( level );
    395           the_period->state = RATE_MONOTONIC_ACTIVE;
    396           the_period->owner_ticks_executed_at_period =
    397             _Thread_Executing->ticks_executed;
    398           the_period->time_at_period = _Watchdog_Ticks_since_boot;
    399 
    400           _Watchdog_Insert_ticks( &the_period->Timer, length );
    401           _Thread_Enable_dispatch();
    402           return RTEMS_TIMEOUT;
    403 
    404         case RATE_MONOTONIC_OWNER_IS_BLOCKING:
    405         case RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING:
    406           /*
    407            *  These should never happen.
    408            */
    409           break;
    410       }
    411   }
    412 
    413   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    414 }
    415 
    416 /*PAGE
    417  *
    418  *  _Rate_monotonic_Timeout
    419  *
    420  *  This routine processes a period ending.  If the owning thread
    421  *  is waiting for the period, that thread is unblocked and the
    422  *  period reinitiated.  Otherwise, the period is expired.
    423  *  This routine is called by the watchdog handler.
    424  *
    425  *  Input parameters:
    426  *    id - period id
    427  *
    428  *  Output parameters: NONE
    429  */
    430 
    431 void _Rate_monotonic_Timeout(
    432   Objects_Id  id,
    433   void       *ignored
    434 )
    435 {
    436   Rate_monotonic_Control *the_period;
    437   Objects_Locations       location;
    438   Thread_Control         *the_thread;
    439 
    440   the_period = _Rate_monotonic_Get( id, &location );
    441   switch ( location ) {
    442     case OBJECTS_REMOTE:  /* impossible */
    443     case OBJECTS_ERROR:
    444       break;
    445 
    446     case OBJECTS_LOCAL:
    447       the_thread = the_period->owner;
    448       if ( _States_Is_waiting_for_period( the_thread->current_state ) &&
    449             the_thread->Wait.id == the_period->Object.id ) {
    450         _Thread_Unblock( the_thread );
    451         the_period->owner_ticks_executed_at_period =
    452           the_thread->ticks_executed;
    453 
    454         the_period->time_at_period = _Watchdog_Ticks_since_boot;
    455 
    456         _Watchdog_Reset( &the_period->Timer );
    457       } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) {
    458         the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING;
    459         the_period->owner_ticks_executed_at_period =
    460           the_thread->ticks_executed;
    461 
    462         the_period->time_at_period = _Watchdog_Ticks_since_boot;
    463         _Watchdog_Reset( &the_period->Timer );
    464       } else
    465         the_period->state = RATE_MONOTONIC_EXPIRED;
    466       _Thread_Unnest_dispatch();
    467       break;
    468   }
    469 }
    470 
  • cpukit/rtems/src/ratemon.c

    rc06d8f64 r5f9b3db  
    5353  );
    5454}
    55 
    56 /*PAGE
    57  *
    58  *  rtems_rate_monotonic_create
    59  *
    60  *  This directive creates a rate monotonic timer and performs
    61  *  some initialization.
    62  *
    63  *  Input parameters:
    64  *    name - name of period
    65  *    id   - pointer to rate monotonic id
    66  *
    67  *  Output parameters:
    68  *    id                - rate monotonic id
    69  *    RTEMS_SUCCESSFUL - if successful
    70  *    error code        - if unsuccessful
    71  */
    72 
    73 rtems_status_code rtems_rate_monotonic_create(
    74   rtems_name    name,
    75   Objects_Id   *id
    76 )
    77 {
    78   Rate_monotonic_Control *the_period;
    79 
    80   if ( !rtems_is_name_valid( name ) )
    81     return RTEMS_INVALID_NAME;
    82 
    83   _Thread_Disable_dispatch();            /* to prevent deletion */
    84 
    85   the_period = _Rate_monotonic_Allocate();
    86 
    87   if ( !the_period ) {
    88     _Thread_Enable_dispatch();
    89     return RTEMS_TOO_MANY;
    90   }
    91 
    92   the_period->owner = _Thread_Executing;
    93   the_period->state = RATE_MONOTONIC_INACTIVE;
    94 
    95   _Objects_Open( &_Rate_monotonic_Information, &the_period->Object, &name );
    96 
    97   *id = the_period->Object.id;
    98   _Thread_Enable_dispatch();
    99   return RTEMS_SUCCESSFUL;
    100 }
    101 
    102 /*PAGE
    103  *
    104  *  rtems_rate_monotonic_ident
    105  *
    106  *  This directive returns the system ID associated with
    107  *  the rate monotonic period name.
    108  *
    109  *  Input parameters:
    110  *    name - user defined period name
    111  *    id   - pointer to period id
    112  *
    113  *  Output parameters:
    114  *    *id               - region id
    115  *    RTEMS_SUCCESSFUL - if successful
    116  *    error code        - if unsuccessful
    117  */
    118 
    119 rtems_status_code rtems_rate_monotonic_ident(
    120   rtems_name    name,
    121   Objects_Id   *id
    122 )
    123 {
    124   Objects_Name_to_id_errors  status;
    125 
    126   status = _Objects_Name_to_id(
    127     &_Rate_monotonic_Information,
    128     &name,
    129     OBJECTS_SEARCH_LOCAL_NODE,
    130     id
    131   );
    132 
    133   return _Status_Object_name_errors_to_status[ status ];
    134 }
    135 
    136 /*PAGE
    137  *
    138  *  rtems_rate_monotonic_cancel
    139  *
    140  *  This directive allows a thread to cancel a rate monotonic timer.
    141  *
    142  *  Input parameters:
    143  *    id - rate monotonic id
    144  *
    145  *  Output parameters:
    146  *    RTEMS_SUCCESSFUL - if successful and caller is not the owning thread
    147  *    error code        - if unsuccessful
    148  */
    149 
    150 rtems_status_code rtems_rate_monotonic_cancel(
    151   Objects_Id id
    152 )
    153 {
    154   Rate_monotonic_Control *the_period;
    155   Objects_Locations              location;
    156 
    157   the_period = _Rate_monotonic_Get( id, &location );
    158   switch ( location ) {
    159     case OBJECTS_REMOTE:           
    160       return RTEMS_INTERNAL_ERROR;  /* should never return this */
    161 
    162     case OBJECTS_ERROR:
    163       return RTEMS_INVALID_ID;
    164 
    165     case OBJECTS_LOCAL:
    166       if ( !_Thread_Is_executing( the_period->owner ) ) {
    167         _Thread_Enable_dispatch();
    168         return RTEMS_NOT_OWNER_OF_RESOURCE;
    169       }
    170       (void) _Watchdog_Remove( &the_period->Timer );
    171       the_period->state = RATE_MONOTONIC_INACTIVE;
    172       _Thread_Enable_dispatch();
    173       return RTEMS_SUCCESSFUL;
    174   }
    175 
    176   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    177 }
    178 
    179 /*PAGE
    180  *
    181  *  rtems_rate_monotonic_delete
    182  *
    183  *  This directive allows a thread to delete a rate monotonic timer.
    184  *
    185  *  Input parameters:
    186  *    id - rate monotonic id
    187  *
    188  *  Output parameters:
    189  *    RTEMS_SUCCESSFUL - if successful
    190  *    error code        - if unsuccessful
    191  */
    192 
    193 rtems_status_code rtems_rate_monotonic_delete(
    194   Objects_Id id
    195 )
    196 {
    197   Rate_monotonic_Control *the_period;
    198   Objects_Locations              location;
    199 
    200   the_period = _Rate_monotonic_Get( id, &location );
    201   switch ( location ) {
    202     case OBJECTS_REMOTE:            /* should never return this */
    203       return RTEMS_INTERNAL_ERROR;
    204 
    205     case OBJECTS_ERROR:
    206       return RTEMS_INVALID_ID;
    207 
    208     case OBJECTS_LOCAL:
    209       _Objects_Close( &_Rate_monotonic_Information, &the_period->Object );
    210       (void) _Watchdog_Remove( &the_period->Timer );
    211       the_period->state = RATE_MONOTONIC_INACTIVE;
    212       _Rate_monotonic_Free( the_period );
    213       _Thread_Enable_dispatch();
    214       return RTEMS_SUCCESSFUL;
    215   }
    216 
    217   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    218 }
    219 
    220 /*PAGE
    221  *
    222  *  rtems_rate_monotonic_get_status
    223  *
    224  *  This directive allows a thread to obtain status information on a
    225  *  period.
    226  *
    227  *  Input parameters:
    228  *    id     - rate monotonic id
    229  *    status - pointer to status control block
    230  *
    231  *  Output parameters:
    232  *    RTEMS_SUCCESSFUL - if successful
    233  *    error code        - if unsuccessful
    234  *
    235  */
    236 
    237 rtems_status_code rtems_rate_monotonic_get_status(
    238   Objects_Id                           id,
    239   rtems_rate_monotonic_period_status  *status
    240 )
    241 {
    242   Objects_Locations              location;
    243   Rate_monotonic_Control        *the_period;
    244 
    245   if ( status == NULL )
    246     return RTEMS_INVALID_ADDRESS;
    247 
    248   the_period = _Rate_monotonic_Get( id, &location );
    249   switch ( location ) {
    250     case OBJECTS_REMOTE:            /* should never return this */
    251       return RTEMS_INTERNAL_ERROR;
    252 
    253     case OBJECTS_ERROR:
    254       return RTEMS_INVALID_ID;
    255 
    256     case OBJECTS_LOCAL:
    257       status->state = the_period->state;
    258 
    259       if ( status->state == RATE_MONOTONIC_INACTIVE ) {
    260         status->ticks_since_last_period = 0;
    261         status->ticks_executed_since_last_period = 0;
    262       } else {
    263         status->ticks_since_last_period =
    264           _Watchdog_Ticks_since_boot - the_period->time_at_period;
    265 
    266         status->ticks_executed_since_last_period =
    267           the_period->owner->ticks_executed -
    268             the_period->owner_ticks_executed_at_period;
    269       }
    270 
    271       _Thread_Enable_dispatch();
    272       return RTEMS_SUCCESSFUL;
    273   }
    274 
    275   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    276 }
    277 
    278 
    279 /*PAGE
    280  *
    281  *  rtems_rate_monotonic_period
    282  *
    283  *  This directive allows a thread to manipulate a rate monotonic timer.
    284  *
    285  *  Input parameters:
    286  *    id     - rate monotonic id
    287  *    length - length of period (in ticks)
    288  *
    289  *  Output parameters:
    290  *    RTEMS_SUCCESSFUL - if successful
    291  *    error code        - if unsuccessful
    292  */
    293 
    294 rtems_status_code rtems_rate_monotonic_period(
    295   Objects_Id        id,
    296   rtems_interval    length
    297 )
    298 {
    299   Rate_monotonic_Control              *the_period;
    300   Objects_Locations                    location;
    301   rtems_status_code                    return_value;
    302   rtems_rate_monotonic_period_states   local_state;
    303   ISR_Level                            level;
    304 
    305   the_period = _Rate_monotonic_Get( id, &location );
    306   switch ( location ) {
    307     case OBJECTS_REMOTE:            /* should never return this */
    308       return RTEMS_INTERNAL_ERROR;
    309 
    310     case OBJECTS_ERROR:
    311       return RTEMS_INVALID_ID;
    312 
    313     case OBJECTS_LOCAL:
    314       if ( !_Thread_Is_executing( the_period->owner ) ) {
    315         _Thread_Enable_dispatch();
    316         return RTEMS_NOT_OWNER_OF_RESOURCE;
    317       }
    318 
    319       if ( length == RTEMS_PERIOD_STATUS ) {
    320         switch ( the_period->state ) {
    321           case RATE_MONOTONIC_INACTIVE:
    322             return_value = RTEMS_NOT_DEFINED;
    323             break;
    324           case RATE_MONOTONIC_ACTIVE:
    325             return_value = RTEMS_SUCCESSFUL;
    326             break;
    327           case RATE_MONOTONIC_EXPIRED:
    328             return_value = RTEMS_TIMEOUT;
    329             break;
    330           default:              /* unreached -- only to remove warnings */
    331             return_value = RTEMS_INTERNAL_ERROR;
    332             break;
    333         }
    334         _Thread_Enable_dispatch();
    335         return( return_value );
    336       }
    337 
    338       _ISR_Disable( level );
    339       switch ( the_period->state ) {
    340         case RATE_MONOTONIC_INACTIVE:
    341           _ISR_Enable( level );
    342           the_period->state = RATE_MONOTONIC_ACTIVE;
    343           _Watchdog_Initialize(
    344             &the_period->Timer,
    345             _Rate_monotonic_Timeout,
    346             id,
    347             NULL
    348           );
    349 
    350           the_period->owner_ticks_executed_at_period =
    351             _Thread_Executing->ticks_executed;
    352 
    353           the_period->time_at_period = _Watchdog_Ticks_since_boot;
    354 
    355           _Watchdog_Insert_ticks( &the_period->Timer, length );
    356           _Thread_Enable_dispatch();
    357           return RTEMS_SUCCESSFUL;
    358 
    359         case RATE_MONOTONIC_ACTIVE:
    360           /*
    361            *  This tells the _Rate_monotonic_Timeout that this task is
    362            *  in the process of blocking on the period.
    363            */
    364 
    365           the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING;
    366           _ISR_Enable( level );
    367 
    368           _Thread_Executing->Wait.id = the_period->Object.id;
    369           _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
    370          
    371           /*
    372            *  Did the watchdog timer expire while we were actually blocking
    373            *  on it?
    374            */
    375 
    376           _ISR_Disable( level );
    377             local_state = the_period->state;
    378             the_period->state = RATE_MONOTONIC_ACTIVE;
    379           _ISR_Enable( level );
    380 
    381           /*
    382            *  If it did, then we want to unblock ourself and continue as
    383            *  if nothing happen.  The period was reset in the timeout routine.
    384            */
    385 
    386           if ( local_state == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING )
    387             _Thread_Clear_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
    388 
    389           _Thread_Enable_dispatch();
    390           return RTEMS_SUCCESSFUL;
    391           break;
    392 
    393         case RATE_MONOTONIC_EXPIRED:
    394           _ISR_Enable( level );
    395           the_period->state = RATE_MONOTONIC_ACTIVE;
    396           the_period->owner_ticks_executed_at_period =
    397             _Thread_Executing->ticks_executed;
    398           the_period->time_at_period = _Watchdog_Ticks_since_boot;
    399 
    400           _Watchdog_Insert_ticks( &the_period->Timer, length );
    401           _Thread_Enable_dispatch();
    402           return RTEMS_TIMEOUT;
    403 
    404         case RATE_MONOTONIC_OWNER_IS_BLOCKING:
    405         case RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING:
    406           /*
    407            *  These should never happen.
    408            */
    409           break;
    410       }
    411   }
    412 
    413   return RTEMS_INTERNAL_ERROR;   /* unreached - only to remove warnings */
    414 }
    415 
    416 /*PAGE
    417  *
    418  *  _Rate_monotonic_Timeout
    419  *
    420  *  This routine processes a period ending.  If the owning thread
    421  *  is waiting for the period, that thread is unblocked and the
    422  *  period reinitiated.  Otherwise, the period is expired.
    423  *  This routine is called by the watchdog handler.
    424  *
    425  *  Input parameters:
    426  *    id - period id
    427  *
    428  *  Output parameters: NONE
    429  */
    430 
    431 void _Rate_monotonic_Timeout(
    432   Objects_Id  id,
    433   void       *ignored
    434 )
    435 {
    436   Rate_monotonic_Control *the_period;
    437   Objects_Locations       location;
    438   Thread_Control         *the_thread;
    439 
    440   the_period = _Rate_monotonic_Get( id, &location );
    441   switch ( location ) {
    442     case OBJECTS_REMOTE:  /* impossible */
    443     case OBJECTS_ERROR:
    444       break;
    445 
    446     case OBJECTS_LOCAL:
    447       the_thread = the_period->owner;
    448       if ( _States_Is_waiting_for_period( the_thread->current_state ) &&
    449             the_thread->Wait.id == the_period->Object.id ) {
    450         _Thread_Unblock( the_thread );
    451         the_period->owner_ticks_executed_at_period =
    452           the_thread->ticks_executed;
    453 
    454         the_period->time_at_period = _Watchdog_Ticks_since_boot;
    455 
    456         _Watchdog_Reset( &the_period->Timer );
    457       } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) {
    458         the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING;
    459         the_period->owner_ticks_executed_at_period =
    460           the_thread->ticks_executed;
    461 
    462         the_period->time_at_period = _Watchdog_Ticks_since_boot;
    463         _Watchdog_Reset( &the_period->Timer );
    464       } else
    465         the_period->state = RATE_MONOTONIC_EXPIRED;
    466       _Thread_Unnest_dispatch();
    467       break;
    468   }
    469 }
    470 
Note: See TracChangeset for help on using the changeset viewer.