Beispiel #1
0
bool _Scheduler_Set_affinity(
  Thread_Control       *the_thread,
  size_t                cpusetsize,
  const cpu_set_t      *cpuset
)
{
  Processor_mask             affinity;
  Processor_mask_Copy_status status;
  const Scheduler_Control   *scheduler;
  Scheduler_Node            *node;
  ISR_lock_Context           lock_context;
  bool                       ok;

  status = _Processor_mask_From_cpu_set_t( &affinity, cpusetsize, cpuset );
  if ( !_Processor_mask_Is_at_most_partial_loss( status ) ) {
    return false;
  }

  /*
   * Reduce affinity set to the online processors to be in line with
   * _Thread_Initialize() which sets the default affinity to the set of online
   * processors.
   */
  _Processor_mask_And( &affinity, _SMP_Get_online_processors(), &affinity );

  scheduler = _Thread_Scheduler_get_home( the_thread );
  _Scheduler_Acquire_critical( scheduler, &lock_context );

  node = _Thread_Scheduler_get_home_node( the_thread );
#if defined(RTEMS_SMP)
  ok = ( *scheduler->Operations.set_affinity )(
    scheduler,
    the_thread,
    node,
    &affinity
  );

  if ( ok ) {
    _Processor_mask_Assign( &the_thread->Scheduler.Affinity, &affinity );
  }
#else
  ok = _Scheduler_default_Set_affinity_body(
    scheduler,
    the_thread,
    node,
    &affinity
  );
#endif

  _Scheduler_Release_critical( scheduler, &lock_context );
  return ok;
}
Beispiel #2
0
static void _Thread_Free( Thread_Control *the_thread )
{
  Thread_Information *information = (Thread_Information *)
    _Objects_Get_information_id( the_thread->Object.id );

  _User_extensions_Thread_delete( the_thread );
  _User_extensions_Destroy_iterators( the_thread );
  _ISR_lock_Destroy( &the_thread->Keys.Lock );
  _Scheduler_Node_destroy(
    _Thread_Scheduler_get_home( the_thread ),
    _Thread_Scheduler_get_home_node( the_thread )
  );
  _ISR_lock_Destroy( &the_thread->Timer.Lock );

  /*
   *  The thread might have been FP.  So deal with that.
   */
#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
  if ( _Thread_Is_allocated_fp( the_thread ) )
    _Thread_Deallocate_fp();
#endif

  _Workspace_Free( the_thread->Start.fp_context );
#endif

  _Freechain_Put(
    &information->Free_thread_queue_heads,
    the_thread->Wait.spare_heads
  );

  /*
   *  Free the rest of the memory associated with this task
   *  and set the associated pointers to NULL for safety.
   */
  _Thread_Stack_Free( the_thread );

  _Workspace_Free( the_thread->Start.tls_area );

#if defined(RTEMS_SMP)
  _ISR_lock_Destroy( &the_thread->Scheduler.Lock );
  _ISR_lock_Destroy( &the_thread->Wait.Lock.Default );
  _SMP_lock_Stats_destroy( &the_thread->Potpourri_stats );
#endif

  _Thread_queue_Destroy( &the_thread->Join_queue );

  _Objects_Free( &information->Objects, &the_thread->Object );
}
Beispiel #3
0
rtems_status_code rtems_task_set_priority(
  rtems_id             id,
  rtems_task_priority  new_priority,
  rtems_task_priority *old_priority_p
)
{
  Thread_Control          *the_thread;
  Thread_queue_Context     queue_context;
  const Scheduler_Control *scheduler;
  Priority_Control         old_priority;
  rtems_status_code        status;

  if ( old_priority_p == NULL ) {
    return RTEMS_INVALID_ADDRESS;
  }

  _Thread_queue_Context_initialize( &queue_context );
  _Thread_queue_Context_clear_priority_updates( &queue_context );
  the_thread = _Thread_Get( id, &queue_context.Lock_context.Lock_context );

  if ( the_thread == NULL ) {
#if defined(RTEMS_MULTIPROCESSING)
    return _RTEMS_tasks_MP_Set_priority( id, new_priority, old_priority_p );
#else
    return RTEMS_INVALID_ID;
#endif
  }

  _Thread_Wait_acquire_critical( the_thread, &queue_context );

  scheduler = _Thread_Scheduler_get_home( the_thread );
  old_priority = _Thread_Get_priority( the_thread );

  if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
    status = _RTEMS_tasks_Set_priority(
      the_thread,
      scheduler,
      new_priority,
      &queue_context
    );
  } else {
    _Thread_Wait_release( the_thread, &queue_context );
    status = RTEMS_SUCCESSFUL;
  }

  *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
  return status;
}
Beispiel #4
0
static int _POSIX_Set_sched_param(
  Thread_Control                       *the_thread,
  int                                   policy,
  struct sched_param                   *param,
  Thread_CPU_budget_algorithms          budget_algorithm,
  Thread_CPU_budget_algorithm_callout   budget_callout,
  Thread_queue_Context                 *queue_context
)
{
  const Scheduler_Control *scheduler;
  POSIX_API_Control       *api;
  int                      normal_prio;
  int                      low_prio;
  bool                     valid;
  Priority_Control         core_normal_prio;
  Priority_Control         core_low_prio;

  normal_prio = param->sched_priority;

  scheduler = _Thread_Scheduler_get_home( the_thread );

  core_normal_prio = _POSIX_Priority_To_core( scheduler, normal_prio, &valid );
  if ( !valid ) {
    return EINVAL;
  }

  if ( policy == SCHED_SPORADIC ) {
    low_prio = param->sched_ss_low_priority;
  } else {
    low_prio = normal_prio;
  }

  core_low_prio = _POSIX_Priority_To_core( scheduler, low_prio, &valid );
  if ( !valid ) {
    return EINVAL;
  }

  api = the_thread->API_Extensions[ THREAD_API_POSIX ];

  _Watchdog_Per_CPU_remove_monotonic( &api->Sporadic.Timer );

  _Priority_Node_set_priority( &the_thread->Real_priority, core_normal_prio );

  if ( _Priority_Node_is_active( &api->Sporadic.Low_priority ) ) {
    _Thread_Priority_add(
      the_thread,
      &the_thread->Real_priority,
      queue_context
    );
    _Thread_Priority_remove(
      the_thread,
      &api->Sporadic.Low_priority,
      queue_context
    );
    _Priority_Node_set_inactive( &api->Sporadic.Low_priority );
  } else {
    _Thread_Priority_changed(
      the_thread,
      &the_thread->Real_priority,
      false,
      queue_context
    );
  }

  the_thread->budget_algorithm = budget_algorithm;
  the_thread->budget_callout   = budget_callout;

  _Priority_Node_set_priority( &api->Sporadic.Low_priority, core_low_prio );
  api->Sporadic.sched_ss_repl_period = param->sched_ss_repl_period;
  api->Sporadic.sched_ss_init_budget = param->sched_ss_init_budget;
  api->Sporadic.sched_ss_max_repl = param->sched_ss_max_repl;

  if ( policy == SCHED_SPORADIC ) {
    _POSIX_Threads_Sporadic_timer_insert( the_thread, api );
  } else {
    the_thread->cpu_time_budget =
      rtems_configuration_get_ticks_per_timeslice();
  }

  return 0;
}