コード例 #1
0
ファイル: schedulerchangeroot.c プロジェクト: Avanznow/rtems
RTEMS_INLINE_ROUTINE bool _Scheduler_Set_root_visitor(
  Resource_Node *resource_node,
  void          *arg
)
{
  Scheduler_Set_root_context *ctx = arg;
  Thread_Control *root = ctx->root;
  Thread_Control *needs_help = root;
  Thread_Control *offers_help =
    THREAD_RESOURCE_NODE_TO_THREAD( resource_node );
  const Scheduler_Control *scheduler = _Scheduler_Get_own( offers_help );
  Thread_Control *needs_help_too;

  _Resource_Node_set_root( resource_node, &root->Resource_node );

  needs_help_too = ( *scheduler->Operations.ask_for_help )(
    scheduler,
    offers_help,
    needs_help
  );

  if ( needs_help_too != needs_help && needs_help_too != NULL ) {
    _Assert( ctx->needs_help == NULL );
    ctx->needs_help = needs_help_too;
  }

  return false;
}
コード例 #2
0
ファイル: threadchangepriority.c プロジェクト: WattTech/rtems
static bool _Thread_Inherit_priority_filter(
  Thread_Control   *inheritor,
  Priority_Control *new_priority,
  void             *arg
)
{
  Thread_Control *ancestor = arg;

  if ( _Scheduler_Get_own( inheritor ) == _Scheduler_Get_own( ancestor ) ) {
    *new_priority = ancestor->current_priority;
  }

  return _Thread_Priority_less_than(
    inheritor->current_priority,
    *new_priority
  );
}
コード例 #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;
  ISR_lock_Context         lock_context;
  const Scheduler_Control *scheduler;
  Priority_Control         old_priority;
  rtems_status_code        status;

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

  the_thread = _Thread_Get( id, &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
  }

  if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
    RTEMS_tasks_Set_priority_context  context;
    Per_CPU_Control                  *cpu_self;

    cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
    _ISR_lock_ISR_enable( &lock_context );

    context.new_priority = new_priority;
    _Thread_Change_priority(
      the_thread,
      0,
      &context,
      _RTEMS_tasks_Set_priority_filter,
      false
    );

    _Thread_Dispatch_enable( cpu_self );
    scheduler = context.scheduler;
    old_priority = context.old_priority;
    status = context.status;
  } else {
    _Thread_State_acquire_critical( the_thread, &lock_context );
    scheduler = _Scheduler_Get_own( the_thread );
    old_priority = _Thread_Get_priority( the_thread );
    _Thread_State_release( the_thread, &lock_context );
    status = RTEMS_SUCCESSFUL;
  }

  *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority );
  return status;
}
コード例 #4
0
static void _Thread_queue_Priority_inherit_enqueue(
  Thread_queue_Queue *queue,
  Thread_Control     *the_thread,
  Thread_queue_Path  *path
)
{
  Thread_queue_Heads *heads;
  Thread_Control     *owner;
  Priority_Control    priority;

  heads = _Thread_queue_Queue_enqueue(
    queue,
    the_thread,
    _Thread_queue_Priority_do_initialize,
    _Thread_queue_Priority_do_enqueue
  );

  owner = queue->owner;

#if defined(RTEMS_SMP)
  if ( _Chain_Has_only_one_node( &heads->Heads.Fifo ) ) {
    priority = the_thread->current_priority;
  } else {
    priority = _Scheduler_Map_priority(
      _Scheduler_Get_own( the_thread ),
      PRIORITY_PSEUDO_ISR
    );
  }
#else
  (void) heads;

  priority = the_thread->current_priority;
#endif

  if ( priority < owner->current_priority ) {
    path->update_priority = owner;

    owner->priority_restore_hint = true;
    _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );

    _Scheduler_Thread_set_priority( owner, priority, false );

    ( *owner->Wait.operations->priority_change )(
      owner->Wait.queue,
      owner,
      priority
    );
  } else {
    path->update_priority = NULL;
  }
}
コード例 #5
0
ファイル: threadqops.c プロジェクト: Avanznow/rtems
static Thread_queue_Priority_queue *_Thread_queue_Priority_queue(
  Thread_queue_Heads   *heads,
  const Thread_Control *the_thread
)
{
#if defined(RTEMS_SMP)
  return &heads->Priority[
    _Scheduler_Get_index( _Scheduler_Get_own( the_thread ) )
  ];
#else
  (void) the_thread;

  return &heads->Heads.Priority;
#endif
}
コード例 #6
0
ファイル: pthreadsetschedprio.c プロジェクト: AoLaD/rtems
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;
}
コード例 #7
0
static bool _RTEMS_tasks_Set_priority_filter(
  Thread_Control   *the_thread,
  Priority_Control *new_priority_p,
  void             *arg
)
{
  RTEMS_tasks_Set_priority_context *context;
  const Scheduler_Control          *scheduler;
  bool                              valid;
  Priority_Control                  current_priority;
  Priority_Control                  new_priority;

  context = arg;
  scheduler = _Scheduler_Get_own( the_thread );
  current_priority = _Thread_Get_priority( the_thread );

  context->scheduler = scheduler;
  context->old_priority = current_priority;

  new_priority = _RTEMS_Priority_To_core(
    scheduler,
    context->new_priority,
    &valid
  );

  *new_priority_p = new_priority;

  if ( !valid ) {
    context->status = RTEMS_INVALID_PRIORITY;
    return false;
  }

  the_thread->real_priority = new_priority;
  context->status = STATUS_SUCCESSFUL;

  return _Thread_Priority_less_than( current_priority, new_priority )
    || !_Thread_Owns_resources( the_thread );
}
コード例 #8
0
static void _Thread_queue_Boost_priority(
  Thread_queue_Heads *heads,
  Thread_Control     *the_thread
)
{
#if defined(RTEMS_SMP)
  if ( !_Chain_Has_only_one_node( &heads->Heads.Fifo ) ) {
    const Scheduler_Control *scheduler;
    Priority_Control         boost_priority;

    the_thread->priority_restore_hint = true;
    _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );

    scheduler = _Scheduler_Get_own( the_thread );
    boost_priority = _Scheduler_Map_priority( scheduler, PRIORITY_PSEUDO_ISR );

    _Scheduler_Thread_set_priority( the_thread, boost_priority, false );
  }
#else
  (void) heads;
  (void) the_thread;
#endif
}
コード例 #9
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;
}