Esempio n. 1
0
void _Thread_queue_Extract_with_return_code(
  Thread_queue_Control *the_thread_queue,
  Thread_Control       *the_thread,
  uint32_t              return_code
)
{
  ISR_lock_Context lock_context;

  _Thread_queue_Acquire( &lock_context );

  if ( !_States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
    _Thread_queue_Release( &lock_context );
    return;
  }

  if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) {
    _Chain_Extract_unprotected( &the_thread->Object.Node );
  } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */
    _RBTree_Extract(
      &the_thread->Wait.queue->Queues.Priority,
      &the_thread->RBNode
    );
    _Thread_Priority_restore_default_change_handler( the_thread );
    _Thread_Lock_restore_default( the_thread );
  }

  the_thread->Wait.return_code = return_code;

  /*
   * We found a thread to unblock.
   *
   * NOTE: This is invoked with interrupts still disabled.
   */
  _Thread_blocking_operation_Finalize( the_thread, &lock_context );
}
Esempio n. 2
0
Scheduler_Void_or_thread _Scheduler_EDF_Yield(
  const Scheduler_Control *scheduler,
  Thread_Control          *the_thread
)
{
  Scheduler_EDF_Context *context =
    _Scheduler_EDF_Get_context( scheduler );
  Scheduler_EDF_Node    *node = _Scheduler_EDF_Thread_get_node( the_thread );

  /*
   * The RBTree has more than one node, enqueue behind the tasks
   * with the same priority in case there are such ones.
   */
  _RBTree_Extract( &context->Ready, &node->Node );
  _RBTree_Insert(
    &context->Ready,
    &node->Node,
    _Scheduler_EDF_Compare,
    false
  );

  _Scheduler_EDF_Schedule_body( scheduler, the_thread, false );

  SCHEDULER_RETURN_VOID_OR_NULL;
}
Esempio n. 3
0
static void _Thread_queue_Priority_priority_change(
  Thread_queue_Queue *queue,
  Thread_Control     *the_thread,
  Priority_Control    new_priority
)
{
  Thread_queue_Heads          *heads;
  Thread_queue_Priority_queue *priority_queue;
  Scheduler_Node              *scheduler_node;

  heads = queue->heads;
  _Assert( heads != NULL );

  priority_queue = _Thread_queue_Priority_queue( heads, the_thread );
  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );

  _RBTree_Extract(
    &priority_queue->Queue,
    &scheduler_node->Wait.Node.RBTree
  );
  _RBTree_Insert_inline(
    &priority_queue->Queue,
    &scheduler_node->Wait.Node.RBTree,
    &new_priority,
    _Thread_queue_Priority_less
  );
}
Esempio n. 4
0
static void _Thread_queue_Priority_do_extract(
  Thread_queue_Heads *heads,
  Thread_Control     *the_thread
)
{
  _RBTree_Extract(
    &heads->Heads.Priority,
    &the_thread->Wait.Node.RBTree
  );
}
void _Scheduler_EDF_Extract(
  Thread_Control     *the_thread
)
{
  Scheduler_EDF_Per_thread *sched_info =
    (Scheduler_EDF_Per_thread*) the_thread->scheduler_info;
  RBTree_Node *node = &(sched_info->Node);

  _RBTree_Extract( &_Scheduler_EDF_Ready_queue, node );
  sched_info->queue_state = SCHEDULER_EDF_QUEUE_STATE_NOT_PRESENTLY;
}
Esempio n. 6
0
static void _Thread_queue_Link_remove( Thread_queue_Link *link )
{
    Thread_queue_Links *links;
    ISR_lock_Context    lock_context;

    links = &_Thread_queue_Links;

    _ISR_lock_Acquire( &links->Lock, &lock_context );
    _RBTree_Extract( &links->Links, &link->Registry_node );
    _ISR_lock_Release( &links->Lock, &lock_context );
}
Esempio n. 7
0
/*
 *  _POSIX_Keys_Run_destructors
 *
 *  17.1.1 Thread-Specific Data Key Create, P1003.1c/Draft 10, p. 163
 *
 *  NOTE:  This is the routine executed when a thread exits to
 *         run through all the keys and do the destructor action.
 */
void _POSIX_Keys_Run_destructors(
  Thread_Control *thread
)
{
  Chain_Control *chain;
  POSIX_Keys_Key_value_pair *iter, *next;
  void *value;
  void (*destructor) (void *);
  POSIX_Keys_Control *the_key;
  Objects_Locations location;

  _Thread_Disable_dispatch();

  chain = &(
      (POSIX_API_Control *)thread->API_Extensions[ THREAD_API_POSIX ]
  )->Key_Chain;
  iter = (POSIX_Keys_Key_value_pair *) _Chain_First( chain );
  while ( !_Chain_Is_tail( chain, &iter->Key_values_per_thread_node ) ) {
    next = (POSIX_Keys_Key_value_pair *)
      _Chain_Next( &iter->Key_values_per_thread_node );

    /**
     * remove key from rbtree and chain.
     * here Chain_Node *iter can be convert to POSIX_Keys_Key_value_pair *,
     * because Chain_Node is the first member of POSIX_Keys_Key_value_pair
     * structure.
     */
    _RBTree_Extract(
        &_POSIX_Keys_Key_value_lookup_tree,
        &iter->Key_value_lookup_node
    );
    _Chain_Extract_unprotected( &iter->Key_values_per_thread_node );

    /**
     * run key value's destructor if destructor and value are both non-null.
     */
    the_key = _POSIX_Keys_Get( iter->key, &location );
    destructor = the_key->destructor;
    value = iter->value;
    if ( destructor != NULL && value != NULL )
      (*destructor)( value );

    _Objects_Put( &the_key->Object );

    _POSIX_Keys_Key_value_pair_free( iter );

    iter = next;
  }

  _Thread_Enable_dispatch();
}
Esempio n. 8
0
void _Scheduler_EDF_Change_priority(
  const Scheduler_Control *scheduler,
  Thread_Control          *the_thread,
  Priority_Control         new_priority,
  bool                     prepend_it
)
{
  Scheduler_EDF_Context *context =
    _Scheduler_EDF_Get_context( scheduler );
  Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );

  _RBTree_Extract( &context->Ready, &node->Node );
  _RBTree_Insert( &context->Ready, &node->Node );
}
Esempio n. 9
0
static void _Thread_queue_Requeue_priority(
  Thread_Control   *the_thread,
  Priority_Control  new_priority,
  void             *context
)
{
  Thread_queue_Control *tq = context;

  _RBTree_Extract( &tq->Queues.Priority, &the_thread->RBNode );
  _RBTree_Insert(
    &tq->Queues.Priority,
    &the_thread->RBNode,
    _Thread_queue_Compare_priority,
    false
  );
}
Esempio n. 10
0
void _Thread_MP_Free_proxy( Thread_Control *the_thread )
{
  Thread_Proxy_control *the_proxy;
  ISR_lock_Context      lock_context;

  the_proxy = (Thread_Proxy_control *) the_thread;

  _Thread_MP_Proxies_acquire( &lock_context );

  _RBTree_Extract( &_Thread_MP_Active_proxies, &the_proxy->Active );
  _Chain_Append_unprotected(
    &_Thread_MP_Inactive_proxies,
    &the_proxy->Object.Node
  );

  _Thread_MP_Proxies_release( &lock_context );
}
Esempio n. 11
0
void _Thread_queue_Requeue(
  Thread_queue_Control *the_thread_queue,
  Thread_Control       *the_thread
)
{
  /*
   * Just in case the thread really wasn't blocked on a thread queue
   * when we get here.
   */
  if ( !the_thread_queue )
    return;

  /*
   * If queueing by FIFO, there is nothing to do. This only applies to
   * priority blocking discipline.
   */
  if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) {
    Thread_queue_Control *tq = the_thread_queue;
    ISR_Level             level;

    _ISR_Disable( level );
    if ( _States_Is_waiting_on_thread_queue( the_thread->current_state ) ) {
      _Thread_queue_Enter_critical_section( tq );

      /* extract the thread */
      _RBTree_Extract(
        &the_thread->Wait.queue->Queues.Priority,
        &the_thread->RBNode
      );

      /* enqueue the thread at the new priority */
      _RBTree_Insert(
        &the_thread_queue->Queues.Priority,
        &the_thread->RBNode,
        _Thread_queue_Compare_priority,
        false
      );
    }
    _ISR_Enable( level );
  }
}
Esempio n. 12
0
static void _Thread_queue_Priority_do_extract(
  Thread_queue_Heads *heads,
  Thread_Control     *the_thread
)
{
  Thread_queue_Priority_queue *priority_queue =
    _Thread_queue_Priority_queue( heads, the_thread );

  _RBTree_Extract(
    &priority_queue->Queue,
    &the_thread->Wait.Node.RBTree
  );

#if defined(RTEMS_SMP)
  _Chain_Extract_unprotected( &priority_queue->Node );

  if ( !_RBTree_Is_empty( &priority_queue->Queue ) ) {
    _Chain_Append_unprotected( &heads->Heads.Fifo, &priority_queue->Node );
  }
#endif
}
Esempio n. 13
0
static void _Thread_queue_Priority_priority_change(
  Thread_Control     *the_thread,
  Priority_Control    new_priority,
  Thread_queue_Queue *queue
)
{
  Thread_queue_Heads *heads = queue->heads;

  _Assert( heads != NULL );

  _RBTree_Extract(
    &heads->Heads.Priority,
    &the_thread->Wait.Node.RBTree
  );
  _RBTree_Insert(
    &heads->Heads.Priority,
    &the_thread->Wait.Node.RBTree,
    _Thread_queue_Compare_priority,
    false
  );
}
Esempio n. 14
0
Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
    const Scheduler_Control *scheduler,
    Thread_Control          *the_thread,
    Priority_Control         new_priority,
    bool                     prepend_it
)
{
    Scheduler_EDF_Context *context =
        _Scheduler_EDF_Get_context( scheduler );
    Scheduler_EDF_Node *node = _Scheduler_EDF_Thread_get_node( the_thread );

    _RBTree_Extract( &context->Ready, &node->Node );
    _RBTree_Insert(
        &context->Ready,
        &node->Node,
        _Scheduler_EDF_Compare,
        false
    );

    SCHEDULER_RETURN_VOID_OR_NULL;
}
Esempio n. 15
0
static void _Thread_queue_Priority_priority_change(
  Thread_Control     *the_thread,
  Priority_Control    new_priority,
  Thread_queue_Queue *queue
)
{
  Thread_queue_Heads          *heads = queue->heads;
  Thread_queue_Priority_queue *priority_queue;

  _Assert( heads != NULL );

  priority_queue = _Thread_queue_Priority_queue( heads, the_thread );

  _RBTree_Extract(
    &priority_queue->Queue,
    &the_thread->Wait.Node.RBTree
  );
  _RBTree_Insert_inline(
    &priority_queue->Queue,
    &the_thread->Wait.Node.RBTree,
    &new_priority,
    _Thread_queue_Priority_less
  );
}