rtems_status_code rtems_rate_monotonic_period( rtems_id id, rtems_interval length ) { Rate_monotonic_Control *the_period; ISR_lock_Context lock_context; Thread_Control *executing; rtems_status_code status; rtems_rate_monotonic_period_states state; the_period = _Rate_monotonic_Get( id, &lock_context ); if ( the_period == NULL ) { return RTEMS_INVALID_ID; } executing = _Thread_Executing; if ( executing != the_period->owner ) { _ISR_lock_ISR_enable( &lock_context ); return RTEMS_NOT_OWNER_OF_RESOURCE; } _Rate_monotonic_Acquire_critical( the_period, &lock_context ); state = the_period->state; if ( length == RTEMS_PERIOD_STATUS ) { status = _Rate_monotonic_Get_status_for_state( state ); _Rate_monotonic_Release( the_period, &lock_context ); } else { switch ( state ) { case RATE_MONOTONIC_ACTIVE: if( the_period->postponed_jobs > 0 ){ /* * If the number of postponed jobs is not 0, it means the * previous postponed instance is finished without exceeding * the current period deadline. * * Do nothing on the watchdog deadline assignment but release the * next remaining postponed job. */ status = _Rate_monotonic_Block_while_expired( the_period, length, executing, &lock_context ); }else{ /* * Normal case that no postponed jobs and no expiration, so wait for * the period and update the deadline of watchdog accordingly. */ status = _Rate_monotonic_Block_while_active( the_period, length, executing, &lock_context ); } break; case RATE_MONOTONIC_INACTIVE: status = _Rate_monotonic_Activate( the_period, length, executing, &lock_context ); break; default: /* * As now this period was already TIMEOUT, there must be at least one * postponed job recorded by the watchdog. The one which exceeded * the previous deadlines was just finished. * * Maybe there is more than one job postponed due to the preemption or * the previous finished job. */ _Assert( state == RATE_MONOTONIC_EXPIRED ); status = _Rate_monotonic_Block_while_expired( the_period, length, executing, &lock_context ); break; } } return status; }
rtems_status_code rtems_rate_monotonic_period( rtems_id id, rtems_interval length ) { Rate_monotonic_Control *the_period; ISR_lock_Context lock_context; Thread_Control *executing; rtems_status_code status; rtems_rate_monotonic_period_states state; the_period = _Rate_monotonic_Get( id, &lock_context ); if ( the_period == NULL ) { return RTEMS_INVALID_ID; } executing = _Thread_Executing; if ( executing != the_period->owner ) { _ISR_lock_ISR_enable( &lock_context ); return RTEMS_NOT_OWNER_OF_RESOURCE; } _Rate_monotonic_Acquire_critical( the_period, &lock_context ); state = the_period->state; if ( length == RTEMS_PERIOD_STATUS ) { status = _Rate_monotonic_Get_status_for_state( state ); _Rate_monotonic_Release( the_period, &lock_context ); } else { switch ( state ) { case RATE_MONOTONIC_ACTIVE: status = _Rate_monotonic_Block_while_active( the_period, length, executing, &lock_context ); break; case RATE_MONOTONIC_INACTIVE: status = _Rate_monotonic_Activate( the_period, length, executing, &lock_context ); break; default: _Assert( state == RATE_MONOTONIC_EXPIRED ); status = _Rate_monotonic_Block_while_expired( the_period, length, executing, &lock_context ); break; } } return status; }