Ejemplo n.º 1
0
Thread_blocking_operation_States _Thread_queue_Enqueue_fifo (
  Thread_queue_Control *the_thread_queue,
  Thread_Control       *the_thread,
  ISR_Level            *level_p
)
{
  Thread_blocking_operation_States sync_state;
  ISR_Level                        level;

  _ISR_Disable( level );

    sync_state = the_thread_queue->sync_state;
    the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
    if (sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED) {
      _Chain_Append_unprotected(
        &the_thread_queue->Queues.Fifo,
        &the_thread->Object.Node
      );
      the_thread->Wait.queue = the_thread_queue;

      the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
      _ISR_Enable( level );
      return THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED;
    }

  /*
   *  An interrupt completed the thread's blocking request.
   *  For example, the blocking thread could have been given
   *  the mutex by an ISR or timed out.
   *
   *  WARNING! Returning with interrupts disabled!
   */
  *level_p = level;
  return sync_state;
}
Ejemplo n.º 2
0
static void _Thread_Make_zombie( Thread_Control *the_thread )
{
  ISR_lock_Context lock_context;
  Thread_Zombie_control *zombies = &_Thread_Zombies;

  if ( _Thread_Owns_resources( the_thread ) ) {
    _Terminate(
      INTERNAL_ERROR_CORE,
      false,
      INTERNAL_ERROR_RESOURCE_IN_USE
    );
  }

  _Objects_Close(
    _Objects_Get_information_id( the_thread->Object.id ),
    &the_thread->Object
  );

  _Thread_Set_state( the_thread, STATES_ZOMBIE );
  _Thread_queue_Extract_with_proxy( the_thread );
  _Watchdog_Remove_ticks( &the_thread->Timer );

  _ISR_lock_ISR_disable_and_acquire( &zombies->Lock, &lock_context );
  _Chain_Append_unprotected( &zombies->Chain, &the_thread->Object.Node );
  _ISR_lock_Release_and_ISR_enable( &zombies->Lock, &lock_context );
}
Ejemplo n.º 3
0
static void _Thread_queue_Priority_do_enqueue(
  Thread_queue_Heads *heads,
  Thread_Control     *the_thread
)
{
  Thread_queue_Priority_queue *priority_queue;
  Scheduler_Node              *scheduler_node;
  Priority_Control             current_priority;

  priority_queue = _Thread_queue_Priority_queue( heads, the_thread );

#if defined(RTEMS_SMP)
  if ( _RBTree_Is_empty( &priority_queue->Queue ) ) {
    _Chain_Append_unprotected( &heads->Heads.Fifo, &priority_queue->Node );
  }
#endif

  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
  current_priority = _Thread_Get_priority( the_thread );

  _RBTree_Initialize_node( &scheduler_node->Wait.Node.RBTree );
  _RBTree_Insert_inline(
    &priority_queue->Queue,
    &scheduler_node->Wait.Node.RBTree,
    &current_priority,
    _Thread_queue_Priority_less
  );
}
void _Scheduler_priority_Yield(void)
{
  Scheduler_priority_Per_thread *sched_info;
  ISR_Level                      level;
  Thread_Control                *executing;
  Chain_Control                 *ready;

  executing  = _Thread_Executing;
  sched_info = (Scheduler_priority_Per_thread *) executing->scheduler_info;
  ready      = sched_info->ready_chain;
  _ISR_Disable( level );
    if ( !_Chain_Has_only_one_node( ready ) ) {
      _Chain_Extract_unprotected( &executing->Object.Node );
      _Chain_Append_unprotected( ready, &executing->Object.Node );

      _ISR_Flash( level );

      if ( _Thread_Is_heir( executing ) )
        _Thread_Heir = (Thread_Control *) _Chain_First( ready );
      _Thread_Dispatch_necessary = true;
    }
    else if ( !_Thread_Is_heir( executing ) )
      _Thread_Dispatch_necessary = true;

  _ISR_Enable( level );
}
Ejemplo n.º 5
0
void _Thread_Reset_timeslice( void )
{
  ISR_Level       level;
  Thread_Control *executing;
  Chain_Control  *ready;

  executing = _Thread_Executing;
  ready     = executing->ready;
  _ISR_Disable( level );
    if ( _Chain_Has_only_one_node( ready ) ) {
      _ISR_Enable( level );
      return;
    }
    _Chain_Extract_unprotected( &executing->Object.Node );
    _Chain_Append_unprotected( ready, &executing->Object.Node );

  _ISR_Flash( level );

    if ( _Thread_Is_heir( executing ) )
      _Thread_Heir = (Thread_Control *) ready->first;

    _Context_Switch_necessary = true;

  _ISR_Enable( level );
}
Ejemplo n.º 6
0
void _Chain_Append(
  Chain_Control *the_chain,
  Chain_Node    *node
)
{
    _Chain_Append_unprotected( the_chain, node );
}
boolean _POSIX_signals_Clear_signals(
  POSIX_API_Control  *api,
  int                 signo,
  siginfo_t          *info,
  boolean             is_global,
  boolean             check_blocked
)
{
  sigset_t                    mask;
  sigset_t                    signals_blocked;
  ISR_Level                   level;
  boolean                     do_callout;
  POSIX_signals_Siginfo_node *psiginfo;

  mask = signo_to_mask( signo );

  do_callout = FALSE;

  /* set blocked signals based on if checking for them, SIGNAL_ALL_MASK
   * insures that no signals are blocked and all are checked.
   */

  if ( check_blocked )
    signals_blocked = ~api->signals_blocked;
  else
    signals_blocked = SIGNAL_ALL_MASK;

  /* XXX this is not right for siginfo type signals yet */
  /* XXX since they can't be cleared the same way */

  _ISR_Disable( level );
    if ( is_global ) {
       if ( mask & (_POSIX_signals_Pending & signals_blocked) ) {
         if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) {
           psiginfo = (POSIX_signals_Siginfo_node *)
             _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] );
           if ( _Chain_Is_empty( &_POSIX_signals_Siginfo[ signo ] ) )
             _POSIX_signals_Clear_process_signals( mask );
           if ( psiginfo ) {
             *info = psiginfo->Info;
             _Chain_Append_unprotected(
               &_POSIX_signals_Inactive_siginfo,
               &psiginfo->Node
             );
           } else
             do_callout = FALSE;
         } else
           _POSIX_signals_Clear_process_signals( mask );
         do_callout = TRUE;
       }
    } else {
      if ( mask & (api->signals_pending & signals_blocked) ) {
        api->signals_pending &= ~mask;
        do_callout = TRUE;
      }
    }
  _ISR_Enable( level );
  return do_callout;
}
Ejemplo n.º 8
0
void _Watchdog_Insert_locked(
  Watchdog_Header  *header,
  Watchdog_Control *the_watchdog,
  ISR_lock_Context *lock_context
)
{
  if ( the_watchdog->state == WATCHDOG_INACTIVE ) {
    Watchdog_Iterator  iterator;
    Chain_Node        *current;
    Chain_Node        *next;
    Watchdog_Interval  delta;

    the_watchdog->state = WATCHDOG_BEING_INSERTED;

    _Chain_Append_unprotected( &header->Iterators, &iterator.Node );

    delta = the_watchdog->initial;
    current = _Chain_Head( &header->Watchdogs );

    while (
      ( next = _Chain_Next( current ) ) != _Chain_Tail( &header->Watchdogs )
    ) {
      Watchdog_Control  *next_watchdog;
      Watchdog_Interval  delta_next;

      next_watchdog = (Watchdog_Control *) next;
      delta_next = next_watchdog->delta_interval;

      if ( delta < delta_next ) {
        _Watchdog_Insert_fixup( header, next_watchdog, delta );
        break;
      }

      iterator.delta_interval = delta - delta_next;
      iterator.current = next;

      _Watchdog_Flash( header, lock_context );

      if ( the_watchdog->state != WATCHDOG_BEING_INSERTED ) {
        goto abort_insert;
      }

      delta = iterator.delta_interval;
      current = iterator.current;
    }

    the_watchdog->delta_interval = delta;
    the_watchdog->start_time = _Watchdog_Ticks_since_boot;
    _Watchdog_Activate( the_watchdog );
    _Chain_Insert_unprotected( current, &the_watchdog->Node );

abort_insert:

    _Chain_Extract_unprotected( &iterator.Node );
  }
}
Ejemplo n.º 9
0
static void _Thread_Add_to_zombie_chain( Thread_Control *the_thread )
{
  ISR_lock_Context       lock_context;
  Thread_Zombie_control *zombies;

  zombies = &_Thread_Zombies;
  _ISR_lock_ISR_disable_and_acquire( &zombies->Lock, &lock_context );
  _Chain_Append_unprotected( &zombies->Chain, &the_thread->Object.Node );
  _ISR_lock_Release_and_ISR_enable( &zombies->Lock, &lock_context );
}
Ejemplo n.º 10
0
static void _Thread_queue_FIFO_do_enqueue(
  Thread_queue_Heads *heads,
  Thread_Control     *the_thread
)
{
  _Chain_Append_unprotected(
    &heads->Heads.Fifo,
    &the_thread->Wait.Node.Chain
  );
}
Ejemplo n.º 11
0
void rtems_chain_append(
    rtems_chain_control *chain,
    rtems_chain_node *node
)
{
    ISR_Level level;

    _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
    _Chain_Append_unprotected( &chain->Chain, node );
    _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
}
Ejemplo n.º 12
0
void rtems_chain_append(
  rtems_chain_control *chain,
  rtems_chain_node *node
)
{
  rtems_interrupt_lock_context lock_context;

  chain_acquire( &lock_context );
  _Chain_Append_unprotected( chain, node );
  chain_release( &lock_context );
}
Ejemplo n.º 13
0
void _Chain_Append(
  Chain_Control *the_chain,
  Chain_Node    *node
)
{
  ISR_Level level;

  _ISR_Disable( level );
    _Chain_Append_unprotected( the_chain, node );
  _ISR_Enable( level );
}
Ejemplo n.º 14
0
void _Scheduler_simple_smp_Start_idle(
  Thread_Control *thread,
  Per_CPU_Control *cpu
)
{
  Scheduler_simple_smp_Control *self = _Scheduler_simple_smp_Instance();

  thread->is_scheduled = true;
  thread->cpu = cpu;
  _Chain_Append_unprotected( &self->scheduled, &thread->Object.Node );
}
Ejemplo n.º 15
0
static void _Thread_queue_FIFO_do_enqueue(
  Thread_queue_Heads *heads,
  Thread_Control     *the_thread
)
{
  Scheduler_Node *scheduler_node;

  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );

  _Chain_Initialize_node( &scheduler_node->Wait.Node.Chain );
  _Chain_Append_unprotected(
    &heads->Heads.Fifo,
    &scheduler_node->Wait.Node.Chain
  );
}
Ejemplo n.º 16
0
void _Scheduler_SMP_Start_idle(
  const Scheduler_Control *scheduler,
  Thread_Control *thread,
  Per_CPU_Control *cpu
)
{
  Scheduler_Context *context = _Scheduler_Get_context( scheduler );
  Scheduler_SMP_Context *self = _Scheduler_SMP_Get_self( context );
  Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );

  node->state = SCHEDULER_SMP_NODE_SCHEDULED;

  _Thread_Set_CPU( thread, cpu );
  _Chain_Append_unprotected( &self->Scheduled, &thread->Object.Node );
}
Ejemplo n.º 17
0
void _Thread_Resume(
  Thread_Control   *the_thread,
  bool              force
)
{

  ISR_Level       level;
  States_Control  current_state;

  _ISR_Disable( level );

  #if defined(RTEMS_ITRON_API)
    if ( force == true )
      the_thread->suspend_count = 0;
    else
      the_thread->suspend_count--;

    if ( the_thread->suspend_count > 0 ) {
      _ISR_Enable( level );
      return;
    }
  #endif

  current_state = the_thread->current_state;
  if ( current_state & STATES_SUSPENDED ) {
    current_state =
    the_thread->current_state = _States_Clear(STATES_SUSPENDED, current_state);

    if ( _States_Is_ready( current_state ) ) {

      _Priority_Add_to_bit_map( &the_thread->Priority_map );

      _Chain_Append_unprotected(the_thread->ready, &the_thread->Object.Node);

      _ISR_Flash( level );

      if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
        _Thread_Heir = the_thread;
        if ( _Thread_Executing->is_preemptible ||
             the_thread->current_priority == 0 )
          _Context_Switch_necessary = true;
      }
    }
  }

  _ISR_Enable( level );
}
Ejemplo n.º 18
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 );
}
void _Thread_Clear_state(
  Thread_Control *the_thread,
  States_Control  state
)
{
  ISR_Level       level;
  States_Control  current_state;

  _ISR_Disable( level );
    current_state = the_thread->current_state;

    if ( current_state & state ) {
      current_state =
      the_thread->current_state = _States_Clear( state, current_state );

      if ( _States_Is_ready( current_state ) ) {

        _Priority_Add_to_bit_map( &the_thread->Priority_map );

        _Chain_Append_unprotected(the_thread->ready, &the_thread->Object.Node);

        _ISR_Flash( level );

        /*
         *  If the thread that was unblocked is more important than the heir,
         *  then we have a new heir.  This may or may not result in a
         *  context switch.
         *
         *  Normal case:
         *    If the current thread is preemptible, then we need to do
         *    a context switch.
         *  Pseudo-ISR case:
         *    Even if the thread isn't preemptible, if the new heir is
         *    a pseudo-ISR system task, we need to do a context switch.
         */
        if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
          _Thread_Heir = the_thread;
          if ( _Thread_Executing->is_preemptible ||
               the_thread->current_priority == 0 )
            _Context_Switch_necessary = true;
        }
      }
  }
  _ISR_Enable( level );
}
Ejemplo n.º 20
0
void _CORE_message_queue_Insert_message(
  CORE_message_queue_Control        *the_message_queue,
  CORE_message_queue_Buffer_control *the_message,
  CORE_message_queue_Submit_types    submit_type
)
{
  Chain_Control *pending_messages;
#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
  bool           notify;
#endif

  _CORE_message_queue_Set_message_priority( the_message, submit_type );
  pending_messages = &the_message_queue->Pending_messages;

#if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
  notify = ( the_message_queue->number_of_pending_messages == 0 );
#endif
  ++the_message_queue->number_of_pending_messages;

  if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST ) {
    _Chain_Append_unprotected( pending_messages, &the_message->Node );
#if defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
  } else  if ( submit_type != CORE_MESSAGE_QUEUE_URGENT_REQUEST ) {
    _Chain_Insert_ordered_unprotected(
      pending_messages,
      &the_message->Node,
      _CORE_message_queue_Order
    );
#endif
  } else {
    _Chain_Prepend_unprotected( pending_messages, &the_message->Node );
  }

  #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
    /*
     *  According to POSIX, does this happen before or after the message
     *  is actually enqueued.  It is logical to think afterwards, because
     *  the message is actually in the queue at this point.
     */
    if ( notify && the_message_queue->notify_handler )
      (*the_message_queue->notify_handler)(the_message_queue->notify_argument);
  #endif
}
Ejemplo n.º 21
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
}
Ejemplo n.º 22
0
static void _Thread_queue_Priority_do_enqueue(
  Thread_queue_Heads *heads,
  Thread_Control     *the_thread
)
{
  Thread_queue_Priority_queue *priority_queue =
    _Thread_queue_Priority_queue( heads, the_thread );

#if defined(RTEMS_SMP)
  if ( _RBTree_Is_empty( &priority_queue->Queue ) ) {
    _Chain_Append_unprotected( &heads->Heads.Fifo, &priority_queue->Node );
  }
#endif

  _RBTree_Insert(
    &priority_queue->Queue,
    &the_thread->Wait.Node.RBTree,
    _Thread_queue_Compare_priority,
    false
  );
}
Ejemplo n.º 23
0
void _Thread_Ready(
  Thread_Control *the_thread
)
{
  ISR_Level              level;
  Thread_Control *heir;

  _ISR_Disable( level );

  the_thread->current_state = STATES_READY;

  _Priority_Add_to_bit_map( &the_thread->Priority_map );

  _Chain_Append_unprotected( the_thread->ready, &the_thread->Object.Node );

  _ISR_Flash( level );

 _Thread_Calculate_heir();
/*  Priority_Bit_map_control minor;
  Priority_Bit_map_control major;

  _Bitfield_Find_first_bit( _Priority_Major_bit_map, major );
  _Bitfield_Find_first_bit( _Priority_Bit_map[major], minor );
  Priority_Control My_Pri=(major<< 4) +minor ;
//  My_Pri=My_Pri+0x100;
  Chain_Control *xx;
  *xx=_Thread_Ready_chain[ My_Pri ];

  _Thread_Heir=(Thread_Control *)(xx->first);
 
//  _Thread_Heir = (Thread_Control *)_Thread_Ready_chain[ My_Pri ].first;
*/

  heir = _Thread_Heir;

  if ( !_Thread_Is_executing( heir ) && _Thread_Executing->is_preemptible )
    _Context_Switch_necessary = true;

  _ISR_Enable( level );
}
Ejemplo n.º 24
0
static void _Thread_queue_Path_append_deadlock_thread(
    Thread_Control       *the_thread,
    Thread_queue_Context *queue_context
)
{
    Thread_Control *deadlock;

    /*
     * In case of a deadlock, we must obtain the thread wait default lock for the
     * first thread on the path that tries to enqueue on a thread queue.  This
     * thread can be identified by the thread wait operations.  This lock acquire
     * is necessary for the timeout and explicit thread priority changes, see
     * _Thread_Priority_perform_actions().
     */

    deadlock = NULL;

    while ( the_thread->Wait.operations != &_Thread_queue_Operations_default ) {
        the_thread = the_thread->Wait.queue->owner;
        deadlock = the_thread;
    }

    if ( deadlock != NULL ) {
        Thread_queue_Link *link;

        link = &queue_context->Path.Deadlock;
        _Chain_Initialize_node( &link->Path_node );
        _Chain_Append_unprotected(
            &queue_context->Path.Links,
            &link->Path_node
        );
        link->owner = deadlock;
        link->Lock_context.Wait.queue = NULL;
        _Thread_Wait_acquire_default_critical(
            deadlock,
            &link->Lock_context.Lock_context
        );
    }
}
Ejemplo n.º 25
0
static void _Thread_queue_Priority_do_enqueue(
  Thread_queue_Heads *heads,
  Thread_Control     *the_thread
)
{
  Thread_queue_Priority_queue *priority_queue =
    _Thread_queue_Priority_queue( heads, the_thread );
  Priority_Control current_priority;

#if defined(RTEMS_SMP)
  if ( _RBTree_Is_empty( &priority_queue->Queue ) ) {
    _Chain_Append_unprotected( &heads->Heads.Fifo, &priority_queue->Node );
  }
#endif

  current_priority = the_thread->current_priority;
  _RBTree_Insert_inline(
    &priority_queue->Queue,
    &the_thread->Wait.Node.RBTree,
    &current_priority,
    _Thread_queue_Priority_less
  );
}
Ejemplo n.º 26
0
void _Scheduler_Request_ask_for_help( Thread_Control *the_thread )
{
  ISR_lock_Context lock_context;

  _Thread_Scheduler_acquire_critical( the_thread, &lock_context );

  if ( _Chain_Is_node_off_chain( &the_thread->Scheduler.Help_node ) ) {
    Per_CPU_Control *cpu;

    cpu = _Thread_Get_CPU( the_thread );
    _Per_CPU_Acquire( cpu );

    _Chain_Append_unprotected(
      &cpu->Threads_in_need_for_help,
      &the_thread->Scheduler.Help_node
    );

    _Per_CPU_Release( cpu );

    _Thread_Dispatch_request( _Per_CPU_Get(), cpu );
  }

  _Thread_Scheduler_release_critical( the_thread, &lock_context );
}
Ejemplo n.º 27
0
static
#endif
bool _Thread_queue_Path_acquire_critical(
    Thread_queue_Queue   *queue,
    Thread_Control       *the_thread,
    Thread_queue_Context *queue_context
)
{
    Thread_Control     *owner;
#if defined(RTEMS_SMP)
    Thread_queue_Link  *link;
    Thread_queue_Queue *target;

    /*
     * For an overview please look at the non-SMP part below.  We basically do
     * the same on SMP configurations.  The fact that we may have more than one
     * executing thread and each thread queue has its own SMP lock makes the task
     * a bit more difficult.  We have to avoid deadlocks at SMP lock level, since
     * this would result in an unrecoverable deadlock of the overall system.
     */

    _Chain_Initialize_empty( &queue_context->Path.Links );

    owner = queue->owner;

    if ( owner == NULL ) {
        return true;
    }

    if ( owner == the_thread ) {
        return false;
    }

    _Chain_Initialize_node(
        &queue_context->Path.Start.Lock_context.Wait.Gate.Node
    );
    link = &queue_context->Path.Start;
    _RBTree_Initialize_node( &link->Registry_node );
    _Chain_Initialize_node( &link->Path_node );

    do {
        _Chain_Append_unprotected( &queue_context->Path.Links, &link->Path_node );
        link->owner = owner;

        _Thread_Wait_acquire_default_critical(
            owner,
            &link->Lock_context.Lock_context
        );

        target = owner->Wait.queue;
        link->Lock_context.Wait.queue = target;

        if ( target != NULL ) {
            if ( _Thread_queue_Link_add( link, queue, target ) ) {
                _Thread_queue_Gate_add(
                    &owner->Wait.Lock.Pending_requests,
                    &link->Lock_context.Wait.Gate
                );
                _Thread_Wait_release_default_critical(
                    owner,
                    &link->Lock_context.Lock_context
                );
                _Thread_Wait_acquire_queue_critical( target, &link->Lock_context );

                if ( link->Lock_context.Wait.queue == NULL ) {
                    _Thread_queue_Link_remove( link );
                    _Thread_Wait_release_queue_critical( target, &link->Lock_context );
                    _Thread_Wait_acquire_default_critical(
                        owner,
                        &link->Lock_context.Lock_context
                    );
                    _Thread_Wait_remove_request_locked( owner, &link->Lock_context );
                    _Assert( owner->Wait.queue == NULL );
                    return true;
                }
            } else {
                link->Lock_context.Wait.queue = NULL;
                _Thread_queue_Path_append_deadlock_thread( owner, queue_context );
                return false;
            }
        } else {
            return true;
        }

        link = &owner->Wait.Link;
        queue = target;
        owner = queue->owner;
    } while ( owner != NULL );
#else
    do {
        owner = queue->owner;

        if ( owner == NULL ) {
            return true;
        }

        if ( owner == the_thread ) {
            return false;
        }

        queue = owner->Wait.queue;
    } while ( queue != NULL );
#endif

    return true;
}
Ejemplo n.º 28
0
bool _POSIX_signals_Clear_signals(
  POSIX_API_Control  *api,
  int                 signo,
  siginfo_t          *info,
  bool                is_global,
  bool                check_blocked
)
{
  sigset_t                    mask;
  sigset_t                    signals_blocked;
  ISR_Level                   level;
  bool                        do_callout;
  POSIX_signals_Siginfo_node *psiginfo;

  mask = signo_to_mask( signo );

  do_callout = false;

  /* set blocked signals based on if checking for them, SIGNAL_ALL_MASK
   * insures that no signals are blocked and all are checked.
   */

  if ( check_blocked )
    signals_blocked = ~api->signals_blocked;
  else
    signals_blocked = SIGNAL_ALL_MASK;

  /* XXX is this right for siginfo type signals? */
  /* XXX are we sure they can be cleared the same way? */

  _ISR_Disable( level );
    if ( is_global ) {
       if ( mask & (_POSIX_signals_Pending & signals_blocked) ) {
         if ( _POSIX_signals_Vectors[ signo ].sa_flags == SA_SIGINFO ) {
           psiginfo = (POSIX_signals_Siginfo_node *)
             _Chain_Get_unprotected( &_POSIX_signals_Siginfo[ signo ] );
           _POSIX_signals_Clear_process_signals( signo );
           /*
            *  It may be impossible to get here with an empty chain
            *  BUT until that is proven we need to be defensive and
            *  protect against it.
            */
           if ( psiginfo ) {
             *info = psiginfo->Info;
             _Chain_Append_unprotected(
               &_POSIX_signals_Inactive_siginfo,
               &psiginfo->Node
             );
           } else
             do_callout = false;
         }
         _POSIX_signals_Clear_process_signals( signo );
         do_callout = true;
       }
    } else {
      if ( mask & (api->signals_pending & signals_blocked) ) {
        api->signals_pending &= ~mask;
        do_callout = true;
      }
    }
  _ISR_Enable( level );
  return do_callout;
}
Ejemplo n.º 29
0
void _Thread_queue_Enqueue(
  Thread_queue_Control *the_thread_queue,
  Thread_Control       *the_thread,
  States_Control        state,
  Watchdog_Interval     timeout
)
{
  ISR_lock_Context                 lock_context;
  Thread_blocking_operation_States sync_state;

#if defined(RTEMS_MULTIPROCESSING)
  if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet )
    the_thread = _Thread_MP_Allocate_proxy( state );
  else
#endif
  /*
   *  Set the blocking state for this thread queue in the thread.
   */
  _Thread_Set_state( the_thread, state );

  /*
   *  If the thread wants to timeout, then schedule its timer.
   */
  if ( timeout ) {
    _Watchdog_Initialize(
       &the_thread->Timer,
       _Thread_queue_Timeout,
       the_thread->Object.id,
       NULL
    );

    _Watchdog_Insert_ticks( &the_thread->Timer, timeout );
  }

  /*
   * Now initiate the enqueuing and checking if the blocking operation
   * should be completed or the thread has had its blocking condition
   * satisfied before we got here.
   */
  _Thread_queue_Acquire( &lock_context );

  sync_state = the_thread_queue->sync_state;
  the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;

  if ( sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) {
    /*
     * Invoke the discipline specific enqueue method.
     */
    if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) {
      _Chain_Append_unprotected(
        &the_thread_queue->Queues.Fifo,
        &the_thread->Object.Node
      );
    } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */
      _Thread_Lock_set( the_thread, &_Thread_queue_Lock );
      _Thread_Priority_set_change_handler(
        the_thread,
        _Thread_queue_Requeue_priority,
        the_thread_queue
      );
      _RBTree_Insert(
        &the_thread_queue->Queues.Priority,
        &the_thread->RBNode,
        _Thread_queue_Compare_priority,
        false
      );
    }

    the_thread->Wait.queue = the_thread_queue;
    the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED;
    _Thread_queue_Release( &lock_context );
  } else {
    /* Cancel a blocking operation due to ISR */

    _Assert(
      sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT ||
        sync_state == THREAD_BLOCKING_OPERATION_SATISFIED
    );

    _Thread_blocking_operation_Finalize( the_thread, &lock_context );
  }
}
Ejemplo n.º 30
0
void _Thread_Scheduler_process_requests( Thread_Control *the_thread )
{
  ISR_lock_Context  lock_context;
  Scheduler_Node   *scheduler_node;

  _Thread_Scheduler_acquire_critical( the_thread, &lock_context );

  scheduler_node = the_thread->Scheduler.requests;

  if ( scheduler_node != NULL ) {
    Scheduler_Node *next;
    Scheduler_Node *remove;

    the_thread->Scheduler.requests = NULL;
    remove = NULL;

    do {
      Scheduler_Node_request request;

      request = scheduler_node->Thread.request;
      scheduler_node->Thread.request = SCHEDULER_NODE_REQUEST_NOT_PENDING;

      next = scheduler_node->Thread.next_request;
#if defined(RTEMS_DEBUG)
      scheduler_node->Thread.next_request = NULL;
#endif

      if ( request == SCHEDULER_NODE_REQUEST_ADD ) {
        ++the_thread->Scheduler.helping_nodes;
        _Chain_Append_unprotected(
          &the_thread->Scheduler.Scheduler_nodes,
          &scheduler_node->Thread.Scheduler_node.Chain
        );
      } else if ( request == SCHEDULER_NODE_REQUEST_REMOVE ) {
        --the_thread->Scheduler.helping_nodes;
        _Chain_Extract_unprotected(
          &scheduler_node->Thread.Scheduler_node.Chain
        );
        scheduler_node->Thread.Scheduler_node.next = remove;
        remove = scheduler_node;
      } else {
        _Assert( request == SCHEDULER_NODE_REQUEST_NOTHING );
      }

      scheduler_node = next;
    } while ( scheduler_node != NULL );

    _Thread_Scheduler_release_critical( the_thread, &lock_context );

    scheduler_node = remove;

    while ( scheduler_node != NULL ) {
      const Scheduler_Control *scheduler;
      ISR_lock_Context         lock_context;

      next = scheduler_node->Thread.Scheduler_node.next;
#if defined(RTEMS_DEBUG)
      scheduler_node->Thread.Scheduler_node.next = NULL;
#endif

      scheduler = _Scheduler_Node_get_scheduler( scheduler_node );

      _Scheduler_Acquire_critical( scheduler, &lock_context );
      ( *scheduler->Operations.withdraw_node )(
        scheduler,
        the_thread,
        scheduler_node,
        THREAD_SCHEDULER_READY
      );
      _Scheduler_Release_critical( scheduler, &lock_context );

      scheduler_node = next;
    }
  } else {
    _Thread_Scheduler_release_critical( the_thread, &lock_context );
  }
}