Esempio n. 1
0
static rtems_status_code _RTEMS_tasks_Set_priority(
  Thread_Control          *the_thread,
  const Scheduler_Control *scheduler,
  Priority_Control         new_priority,
  Thread_queue_Context    *queue_context
)
{
  Priority_Control core_new_priority;
  bool             valid;
  Per_CPU_Control *cpu_self;

  core_new_priority = _RTEMS_Priority_To_core(
    scheduler,
    new_priority,
    &valid
  );

  if ( !valid ) {
    _Thread_Wait_release( the_thread, queue_context );
    return RTEMS_INVALID_PRIORITY;
  }

  _Thread_Priority_change(
    the_thread,
    &the_thread->Real_priority,
    core_new_priority,
    false,
    queue_context
  );
  cpu_self = _Thread_queue_Dispatch_disable( queue_context );
  _Thread_Wait_release( the_thread, queue_context );
  _Thread_Priority_update( queue_context );
  _Thread_Dispatch_enable( cpu_self );
  return RTEMS_SUCCESSFUL;
}
Esempio n. 2
0
void _Thread_queue_Extract( Thread_Control *the_thread )
{
    Thread_queue_Context  queue_context;
    Thread_queue_Queue   *queue;

    _Thread_queue_Context_initialize( &queue_context );
    _Thread_Wait_acquire( the_thread, &queue_context );

    queue = the_thread->Wait.queue;

    if ( queue != NULL ) {
        bool unblock;

        _Thread_Wait_remove_request( the_thread, &queue_context.Lock_context );
        _Thread_queue_Context_set_MP_callout(
            &queue_context,
            _Thread_queue_MP_callout_do_nothing
        );
        unblock = _Thread_queue_Extract_locked(
                      queue,
                      the_thread->Wait.operations,
                      the_thread,
                      &queue_context
                  );
        _Thread_queue_Unblock_critical(
            unblock,
            queue,
            the_thread,
            &queue_context.Lock_context.Lock_context
        );
    } else {
        _Thread_Wait_release( the_thread, &queue_context );
    }
}
Esempio n. 3
0
int pthread_setschedprio( pthread_t thread, int prio )
{
  Thread_Control          *the_thread;
  Per_CPU_Control         *cpu_self;
  Thread_queue_Context     queue_context;
  const Scheduler_Control *scheduler;
  Priority_Control         new_priority;
  bool                     valid;

  the_thread = _Thread_Get( thread, &queue_context.Lock_context.Lock_context );

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

  _Thread_queue_Context_clear_priority_updates( &queue_context );
  _Thread_Wait_acquire_critical( the_thread, &queue_context );

  scheduler = _Scheduler_Get_own( the_thread );

  new_priority = _POSIX_Priority_To_core( scheduler, prio, &valid );
  if ( !valid ) {
    _Thread_Wait_release( the_thread, &queue_context );
    return EINVAL;
  }

  _Thread_Priority_change(
    the_thread,
    &the_thread->Real_priority,
    new_priority,
    true,
    &queue_context
  );

  cpu_self = _Thread_Dispatch_disable_critical(
    &queue_context.Lock_context.Lock_context
  );
  _Thread_Wait_release( the_thread, &queue_context );

  _Thread_Priority_update( &queue_context );

  _Thread_Dispatch_enable( cpu_self );
  return 0;
}
Esempio n. 4
0
rtems_status_code rtems_task_set_scheduler(
  rtems_id            task_id,
  rtems_id            scheduler_id,
  rtems_task_priority priority
)
{
  const Scheduler_Control *scheduler;
  Thread_Control          *the_thread;
  Thread_queue_Context     queue_context;
  ISR_lock_Context         state_context;
  Per_CPU_Control         *cpu_self;
  bool                     valid;
  Priority_Control         core_priority;
  Status_Control           status;

  if ( !_Scheduler_Get_by_id( scheduler_id, &scheduler ) ) {
    return RTEMS_INVALID_ID;
  }

  core_priority = _RTEMS_Priority_To_core( scheduler, priority, &valid );
  if ( !valid ) {
    return RTEMS_INVALID_PRIORITY;
  }

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

  if ( the_thread == NULL ) {
#if defined(RTEMS_MULTIPROCESSING)
    if ( _Thread_MP_Is_remote( task_id ) ) {
      return RTEMS_ILLEGAL_ON_REMOTE_OBJECT;
    }
#endif

    return RTEMS_INVALID_ID;
  }

  cpu_self = _Thread_Dispatch_disable_critical(
    &queue_context.Lock_context.Lock_context
  );

  _Thread_Wait_acquire_critical( the_thread, &queue_context );
  _Thread_State_acquire_critical( the_thread, &state_context );

  status = _Scheduler_Set( scheduler, the_thread, core_priority );

  _Thread_State_release_critical( the_thread, &state_context );
  _Thread_Wait_release( the_thread, &queue_context );
  _Thread_Dispatch_enable( cpu_self );
  return _Status_Get( status );
}
Esempio n. 5
0
int pthread_setschedparam(
  pthread_t           thread,
  int                 policy,
  struct sched_param *param
)
{
  Thread_CPU_budget_algorithms         budget_algorithm;
  Thread_CPU_budget_algorithm_callout  budget_callout;
  Thread_Control                      *the_thread;
  Per_CPU_Control                     *cpu_self;
  Thread_queue_Context                 queue_context;
  int                                  error;

  if ( param == NULL ) {
    return EINVAL;
  }

  error = _POSIX_Thread_Translate_sched_param(
    policy,
    param,
    &budget_algorithm,
    &budget_callout
  );
  if ( error != 0 ) {
    return error;
  }

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

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

  _Thread_Wait_acquire_critical( the_thread, &queue_context );
  error = _POSIX_Set_sched_param(
    the_thread,
    policy,
    param,
    budget_algorithm,
    budget_callout,
    &queue_context
  );
  cpu_self = _Thread_queue_Dispatch_disable( &queue_context );
  _Thread_Wait_release( the_thread, &queue_context );
  _Thread_Priority_update( &queue_context );
  _Thread_Dispatch_enable( cpu_self );
  return error;
}
Esempio n. 6
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;
}
Esempio n. 7
0
int pthread_getschedparam(
  pthread_t           thread,
  int                *policy,
  struct sched_param *param
)
{
  Thread_Control          *the_thread;
  Thread_queue_Context     queue_context;
  POSIX_API_Control       *api;
  const Scheduler_Control *scheduler;
  Priority_Control         priority;

  if ( policy == NULL || param == NULL ) {
    return EINVAL;
  }

  the_thread = _Thread_Get( thread, &queue_context.Lock_context );

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

  api = the_thread->API_Extensions[ THREAD_API_POSIX ];

  _Thread_Wait_acquire_critical( the_thread, &queue_context );

  *policy = api->Attributes.schedpolicy;
  *param  = api->Attributes.schedparam;

  scheduler = _Scheduler_Get_own( the_thread );
  priority = the_thread->real_priority;

  _Thread_Wait_release( the_thread, &queue_context );

  param->sched_priority = _POSIX_Priority_From_core( scheduler, priority );
  return 0;
}
Esempio n. 8
0
static void _Thread_Raise_real_priority(
  Thread_Control   *the_thread,
  Priority_Control  priority
)
{
  Thread_queue_Context queue_context;

  _Thread_queue_Context_initialize( &queue_context );
  _Thread_queue_Context_clear_priority_updates( &queue_context );
  _Thread_Wait_acquire( the_thread, &queue_context );

  if ( priority < the_thread->Real_priority.priority ) {
    _Thread_Priority_change(
      the_thread,
      &the_thread->Real_priority,
      priority,
      false,
      &queue_context
    );
  }

  _Thread_Wait_release( the_thread, &queue_context );
  _Thread_Priority_update( &queue_context );
}