Ejemplo n.º 1
0
void _Scheduler_CBS_Budget_callout(
  Thread_Control *the_thread
)
{
  Priority_Control          new_priority;
  Scheduler_CBS_Node       *node;
  Scheduler_CBS_Server_id   server_id;

  /* Put violating task to background until the end of period. */
  new_priority = the_thread->Start.initial_priority;
  if ( the_thread->real_priority != new_priority )
    the_thread->real_priority = new_priority;
  if ( the_thread->current_priority != new_priority )
    _Thread_Change_priority(the_thread, new_priority, true);

  /* Invoke callback function if any. */
  node = _Scheduler_CBS_Thread_get_node( the_thread );
  if ( node->cbs_server->cbs_budget_overrun ) {
    _Scheduler_CBS_Get_server_id(
        node->cbs_server->task_id,
        &server_id
    );
    node->cbs_server->cbs_budget_overrun( server_id );
  }
}
Ejemplo n.º 2
0
void _Scheduler_CBS_Release_job(
  const Scheduler_Control *scheduler,
  Thread_Control          *the_thread,
  uint32_t                 deadline
)
{
  Scheduler_CBS_Node   *node = _Scheduler_CBS_Thread_get_node( the_thread );
  Scheduler_CBS_Server *serv_info = node->cbs_server;
  Priority_Control      new_priority;
  Priority_Control      unused;

  if (deadline) {
    /* Initializing or shifting deadline. */
    if (serv_info)
      new_priority = (_Watchdog_Ticks_since_boot + serv_info->parameters.deadline)
        & ~SCHEDULER_EDF_PRIO_MSB;
    else
      new_priority = (_Watchdog_Ticks_since_boot + deadline)
        & ~SCHEDULER_EDF_PRIO_MSB;
  }
  else {
    /* Switch back to background priority. */
    new_priority = the_thread->Start.initial_priority;
  }

  /* Budget replenishment for the next job. */
  if (serv_info)
    the_thread->cpu_time_budget = serv_info->parameters.budget;

  _Thread_Set_priority( the_thread, new_priority, &unused, true );
}
Ejemplo n.º 3
0
int _Scheduler_CBS_Attach_thread (
  Scheduler_CBS_Server_id server_id,
  rtems_id                task_id
)
{
  Scheduler_CBS_Server *server;
  ISR_lock_Context      lock_context;
  Thread_Control       *the_thread;
  Scheduler_CBS_Node   *node;

  if ( server_id >= _Scheduler_CBS_Maximum_servers ) {
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  }

  server = &_Scheduler_CBS_Server_list[ server_id ];

  if ( !server->initialized ) {
    return SCHEDULER_CBS_ERROR_NOSERVER;
  }

  if ( server->task_id != -1 ) {
    return SCHEDULER_CBS_ERROR_FULL;
  }

  the_thread = _Thread_Get( task_id, &lock_context );

  if ( the_thread == NULL ) {
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  }

  node = _Scheduler_CBS_Thread_get_node( the_thread );

  if ( node->cbs_server != NULL ) {
    _ISR_lock_ISR_enable( &lock_context );
    return SCHEDULER_CBS_ERROR_FULL;
  }

  node->cbs_server = server;

  server->task_id = task_id;

  the_thread->budget_callout   = _Scheduler_CBS_Budget_callout;
  the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
  the_thread->is_preemptible   = true;

  _ISR_lock_ISR_enable( &lock_context );
  return SCHEDULER_CBS_OK;
}
Ejemplo n.º 4
0
int _Scheduler_CBS_Attach_thread (
  Scheduler_CBS_Server_id server_id,
  rtems_id                task_id
)
{
  Objects_Locations location;
  Thread_Control *the_thread;

  if ( server_id >= _Scheduler_CBS_Maximum_servers )
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;

  /* Server is not valid. */
  if ( !_Scheduler_CBS_Server_list[server_id].initialized )
    return SCHEDULER_CBS_ERROR_NOSERVER;

  /* Server is already attached to a thread. */
  if ( _Scheduler_CBS_Server_list[server_id].task_id != -1 )
    return SCHEDULER_CBS_ERROR_FULL;

  the_thread = _Thread_Get(task_id, &location);
  /* The routine _Thread_Get may disable dispatch and not enable again. */
  if ( the_thread ) {
    Scheduler_CBS_Node *node = _Scheduler_CBS_Thread_get_node( the_thread );

    /* Thread is already attached to a server. */
    if ( node->cbs_server ) {
      _Objects_Put( &the_thread->Object );
      return SCHEDULER_CBS_ERROR_FULL;
    }

    _Scheduler_CBS_Server_list[server_id].task_id = task_id;
    node->cbs_server = &_Scheduler_CBS_Server_list[server_id];

    the_thread->budget_callout   = _Scheduler_CBS_Budget_callout;
    the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
    the_thread->is_preemptible   = true;

    _Objects_Put( &the_thread->Object );
  } else {
    return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
  }

  return SCHEDULER_CBS_OK;
}