예제 #1
0
void _Rate_monotonic_Timeout( Watchdog_Control *the_watchdog )
{
  Rate_monotonic_Control *the_period;
  Thread_Control         *owner;
  ISR_lock_Context        lock_context;
  Thread_Wait_flags       wait_flags;

  the_period = RTEMS_CONTAINER_OF( the_watchdog, Rate_monotonic_Control, Timer );
  owner = the_period->owner;

  _ISR_lock_ISR_disable( &lock_context );
  _Rate_monotonic_Acquire_critical( the_period, &lock_context );
  wait_flags = _Thread_Wait_flags_get( owner );

  if (
    ( wait_flags & THREAD_WAIT_CLASS_PERIOD ) != 0
      && owner->Wait.return_argument == the_period
  ) {
    bool unblock;
    bool success;

    owner->Wait.return_argument = NULL;

    success = _Thread_Wait_flags_try_change_release(
      owner,
      RATE_MONOTONIC_INTEND_TO_BLOCK,
      RATE_MONOTONIC_READY_AGAIN
    );
    if ( success ) {
      unblock = false;
    } else {
      _Assert( _Thread_Wait_flags_get( owner ) == RATE_MONOTONIC_BLOCKED );
      _Thread_Wait_flags_set( owner, RATE_MONOTONIC_READY_AGAIN );
      unblock = true;
    }

    _Rate_monotonic_Restart( the_period, owner, &lock_context );

    if ( unblock ) {
      _Thread_Unblock( owner );
    }
  } else {
    _Rate_monotonic_Renew_deadline( the_period, &lock_context );
  }
}
예제 #2
0
rtems_status_code rtems_rate_monotonic_reset_statistics(
  rtems_id id
)
{
  Rate_monotonic_Control *the_period;
  ISR_lock_Context        lock_context;
  Thread_Control         *owner;

  the_period = _Rate_monotonic_Get( id, &lock_context );
  if ( the_period == NULL ) {
    return RTEMS_INVALID_ID;
  }

  owner = the_period->owner;
  _Rate_monotonic_Acquire_critical( owner, &lock_context );
  _Rate_monotonic_Reset_statistics( the_period );
  _Rate_monotonic_Release( owner, &lock_context );
  return RTEMS_SUCCESSFUL;
}
예제 #3
0
void _Rate_monotonic_Cancel(
  Rate_monotonic_Control *the_period,
  Thread_Control         *owner,
  ISR_lock_Context       *lock_context
)
{
  Per_CPU_Control *cpu_self;
  Thread_Control  *update_priority;

  _Rate_monotonic_Acquire_critical( the_period, lock_context );

  _Watchdog_Per_CPU_remove_relative( &the_period->Timer );
  the_period->state = RATE_MONOTONIC_INACTIVE;
  update_priority = _Scheduler_Cancel_job( the_period->owner );

  cpu_self = _Thread_Dispatch_disable_critical( lock_context );
  _Rate_monotonic_Release( the_period, lock_context );
  _Thread_Update_priority( update_priority );
  _Thread_Dispatch_enable( cpu_self );
}
예제 #4
0
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;
}
예제 #5
0
파일: ratemonperiod.c 프로젝트: AoLaD/rtems
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;
}