Esempio n. 1
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. 2
0
static void _Thread_queue_Path_release( Thread_queue_Path *path )
{
#if defined(RTEMS_SMP)
  Chain_Node *head;
  Chain_Node *node;

  head = _Chain_Head( &path->Links );
  node = _Chain_Last( &path->Links );

  if ( head != node ) {
    Thread_queue_Link *link;

    /*
     * The terminal link may have an owner which does not wait on a thread
     * queue.
     */

    link = THREAD_QUEUE_LINK_OF_PATH_NODE( node );

    if ( link->Queue_context.Wait.queue == NULL ) {
      _Thread_Wait_release_default_critical(
        link->owner,
        &link->Queue_context.Lock_context
      );

      node = _Chain_Previous( node );
#if defined(RTEMS_DEBUG)
      _Chain_Set_off_chain( &link->Path_node );
#endif
    }

    while ( head != node ) {
      /* The other links have an owner which waits on a thread queue */
      link = THREAD_QUEUE_LINK_OF_PATH_NODE( node );
      _Assert( link->Queue_context.Wait.queue != NULL );

      _Thread_queue_Link_remove( link );
      _Thread_Wait_release_queue_critical(
        link->Queue_context.Wait.queue,
        &link->Queue_context
      );
      _Thread_Wait_remove_request( link->owner, &link->Queue_context );

      node = _Chain_Previous( node );
#if defined(RTEMS_DEBUG)
      _Chain_Set_off_chain( &link->Path_node );
#endif
    }
  }
#else
  (void) path;
#endif
}
Esempio n. 3
0
static
#endif
void _Thread_queue_Path_release_critical(
    Thread_queue_Context *queue_context
)
{
#if defined(RTEMS_SMP)
    Chain_Node *head;
    Chain_Node *node;

    head = _Chain_Head( &queue_context->Path.Links );
    node = _Chain_Last( &queue_context->Path.Links );

    while ( head != node ) {
        Thread_queue_Link *link;

        link = THREAD_QUEUE_LINK_OF_PATH_NODE( node );

        if ( link->Lock_context.Wait.queue != NULL ) {
            _Thread_queue_Link_remove( link );
            _Thread_Wait_release_queue_critical(
                link->Lock_context.Wait.queue,
                &link->Lock_context
            );
            _Thread_Wait_remove_request( link->owner, &link->Lock_context );
        } else {
            _Thread_Wait_release_default_critical(
                link->owner,
                &link->Lock_context.Lock_context
            );
        }

        node = _Chain_Previous( node );
#if defined(RTEMS_DEBUG)
        _Chain_Set_off_chain( &link->Path_node );
#endif
    }
#else
    (void) queue_context;
#endif
}