void _Thread_Set_transient(
  Thread_Control *the_thread
)
{
  ISR_Level             level;
  uint32_t              old_state;
  Chain_Control *ready;

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

  old_state = the_thread->current_state;
  the_thread->current_state = _States_Set( STATES_TRANSIENT, old_state );

  if ( _States_Is_ready( old_state ) ) {
    if ( _Chain_Has_only_one_node( ready ) ) {

      _Chain_Initialize_empty( ready );
      _Priority_Remove_from_bit_map( &the_thread->Priority_map );

    } else
      _Chain_Extract_unprotected( &the_thread->Object.Node );
  }

  _ISR_Enable( level );

}
Пример #2
0
void _Timer_Cancel( Per_CPU_Control *cpu, Timer_Control *the_timer )
{
  Timer_Classes the_class;

  the_class = the_timer->the_class;

  if ( _Watchdog_Is_scheduled( &the_timer->Ticker ) ) {
    the_timer->stop_time = _Timer_Get_CPU_ticks( cpu );
    _Watchdog_Remove(
      &cpu->Watchdog.Header[ _Timer_Watchdog_header_index( the_class ) ],
      &the_timer->Ticker
    );
  } else if ( _Timer_Is_on_task_class( the_class ) ) {
    Timer_server_Control *timer_server;
    ISR_lock_Context      lock_context;

    timer_server = _Timer_server;
    _Assert( timer_server != NULL );
    _Timer_server_Acquire_critical( timer_server, &lock_context );

    if ( _Watchdog_Get_state( &the_timer->Ticker ) == WATCHDOG_PENDING ) {
      _Watchdog_Set_state( &the_timer->Ticker, WATCHDOG_INACTIVE );
      _Chain_Extract_unprotected( &the_timer->Ticker.Node.Chain );
    }

    _Timer_server_Release_critical( timer_server, &lock_context );
  }
}
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 );
}
Пример #4
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 );
}
Пример #5
0
void _SMP_Multicast_actions_process( void )
{
  SMP_lock_Context      lock_context;
  uint32_t              cpu_self_index;
  SMP_Multicast_action *node;
  SMP_Multicast_action *next;

  _SMP_lock_ISR_disable_and_acquire( &_SMP_Multicast.Lock, &lock_context );
  cpu_self_index = _SMP_Get_current_processor();
  node = (SMP_Multicast_action *) _Chain_First( &_SMP_Multicast.Actions );

  while ( !_Chain_Is_tail( &_SMP_Multicast.Actions, &node->Node ) ) {
    next = (SMP_Multicast_action *) _Chain_Next( &node->Node );

    if ( _Processor_mask_Is_set( &node->targets, cpu_self_index ) ) {
      _Processor_mask_Clear( &node->targets, cpu_self_index );

      ( *node->handler )( node->arg );

      if ( _Processor_mask_Is_zero( &node->targets ) ) {
        _Chain_Extract_unprotected( &node->Node );
        _Atomic_Store_ulong( &node->done, 1, ATOMIC_ORDER_RELEASE );
      }
    }

    node = next;
  }

  _SMP_lock_Release_and_ISR_enable( &_SMP_Multicast.Lock, &lock_context );
}
Пример #6
0
static void _Thread_queue_FIFO_do_extract(
  Thread_queue_Heads *heads,
  Thread_Control     *the_thread
)
{
  _Chain_Extract_unprotected( &the_thread->Wait.Node.Chain );
}
void _POSIX_Threads_cancel_run(
  Thread_Control *the_thread
)
{
  POSIX_Cancel_Handler_control      *handler;
  Chain_Control                     *handler_stack;
  POSIX_API_Control                 *thread_support;
  ISR_Level                          level;

  thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];

  handler_stack = &thread_support->Cancellation_Handlers;

  thread_support->cancelability_state = PTHREAD_CANCEL_DISABLE;

  while ( !_Chain_Is_empty( handler_stack ) ) {
    _ISR_Disable( level );
      handler = (POSIX_Cancel_Handler_control *)
           _Chain_Tail( handler_stack )->previous;
      _Chain_Extract_unprotected( &handler->Node );
    _ISR_Enable( level );

    (*handler->routine)( handler->arg );

    _Workspace_Free( handler );
  }
}
Пример #8
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 );
}
Пример #9
0
static void _Scheduler_simple_smp_Move_from_ready_to_scheduled(
  Chain_Control *scheduled_chain,
  Thread_Control *ready_to_scheduled
)
{
  _Chain_Extract_unprotected( &ready_to_scheduled->Object.Node );
  _Scheduler_simple_Insert_priority_fifo( scheduled_chain, ready_to_scheduled );
}
Пример #10
0
static void update_registry_and_extract(
  Chain_Iterator_registry *reg,
  Chain_Node *n
)
{
  _Chain_Iterator_registry_update( reg, n );
  _Chain_Extract_unprotected( n );
}
Пример #11
0
static void _Scheduler_priority_SMP_Move_from_scheduled_to_ready(
  Scheduler_SMP_Control *self,
  Thread_Control *scheduled_to_ready
)
{
  _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
  _Scheduler_priority_Ready_queue_enqueue_first( scheduled_to_ready );
}
Пример #12
0
void rtems_chain_extract( rtems_chain_node *node )
{
  rtems_interrupt_lock_context lock_context;

  chain_acquire( &lock_context );
  _Chain_Extract_unprotected( node );
  chain_release( &lock_context );
}
Пример #13
0
static void _Scheduler_simple_smp_Move_from_scheduled_to_ready(
  Chain_Control *ready_chain,
  Thread_Control *scheduled_to_ready
)
{
  _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
  _Scheduler_simple_Insert_priority_lifo( ready_chain, scheduled_to_ready );
}
Пример #14
0
static void _Scheduler_simple_SMP_Extract_from_ready(
  Scheduler_Context *context,
  Thread_Control *thread
)
{
  (void) context;

  _Chain_Extract_unprotected( &thread->Object.Node );
}
Пример #15
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 );
  }
}
Пример #16
0
void _Chain_Extract(
  Chain_Node *node
)
{
  ISR_Level level;

  _ISR_Disable( level );
    _Chain_Extract_unprotected( node );
  _ISR_Enable( level );
}
Пример #17
0
static void _Thread_queue_FIFO_do_extract(
  Thread_queue_Heads *heads,
  Thread_Control     *the_thread
)
{
  Scheduler_Node *scheduler_node;

  scheduler_node = _Scheduler_Thread_get_own_node( the_thread );
  _Chain_Extract_unprotected( &scheduler_node->Wait.Node.Chain );
}
Пример #18
0
static void _Watchdog_Remove_it(
  Watchdog_Header   *header,
  Watchdog_Control  *the_watchdog
)
{
  Chain_Node        *next;
  Watchdog_Interval  delta;
  const Chain_Node  *iterator_tail;
  Chain_Node        *iterator_node;

  _Assert( the_watchdog->state == WATCHDOG_ACTIVE );

  the_watchdog->state = WATCHDOG_INACTIVE;
  the_watchdog->stop_time = _Watchdog_Ticks_since_boot;

  next = _Chain_Next( &the_watchdog->Node );
  delta = the_watchdog->delta_interval;

  if ( next != _Chain_Tail( &header->Watchdogs ) ) {
    Watchdog_Control *next_watchdog;

    next_watchdog = (Watchdog_Control *) next;
    next_watchdog->delta_interval += delta;
  }

  _Chain_Extract_unprotected( &the_watchdog->Node );

  iterator_node = _Chain_First( &header->Iterators );
  iterator_tail = _Chain_Immutable_tail( &header->Iterators );

  while ( iterator_node != iterator_tail ) {
    Watchdog_Iterator *iterator;

    iterator = (Watchdog_Iterator *) iterator_node;

    if ( iterator->current == next ) {
      iterator->delta_interval += delta;
    }

    if ( iterator->current == &the_watchdog->Node ) {
      Chain_Node *previous = _Chain_Previous( &the_watchdog->Node );

      iterator->current = previous;

      if ( previous != _Chain_Head( &header->Watchdogs ) ) {
        Watchdog_Control *previous_watchdog;

        previous_watchdog = (Watchdog_Control *) previous;
        iterator->delta_interval += previous_watchdog->delta_interval;
      }
    }

    iterator_node = _Chain_Next( iterator_node );
  }
}
Пример #19
0
void rtems_chain_explicit_extract(
    rtems_chain_control *chain,
    rtems_chain_node *node
)
{
ISR_Level level;

_ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
_Chain_Extract_unprotected( node );
_ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
}
Пример #20
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();
}
Пример #21
0
static void _Scheduler_simple_SMP_Move_from_scheduled_to_ready(
  Scheduler_Context *context,
  Thread_Control *scheduled_to_ready
)
{
  Scheduler_simple_SMP_Context *self =
    _Scheduler_simple_SMP_Get_self( context );

  _Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
  _Scheduler_simple_Insert_priority_lifo(
    &self->Ready,
    scheduled_to_ready
  );
}
Пример #22
0
static void _Scheduler_simple_SMP_Move_from_ready_to_scheduled(
  Scheduler_Context *context,
  Thread_Control *ready_to_scheduled
)
{
  Scheduler_simple_SMP_Context *self =
    _Scheduler_simple_SMP_Get_self( context );

  _Chain_Extract_unprotected( &ready_to_scheduled->Object.Node );
  _Scheduler_simple_Insert_priority_fifo(
    &self->Base.Scheduled,
    ready_to_scheduled
  );
}
Пример #23
0
void pthread_cleanup_pop(
    int    execute
)
{
    POSIX_Cancel_Handler_control      *handler;
    POSIX_Cancel_Handler_control      tmp_handler;
    Chain_Control                     *handler_stack;
    POSIX_API_Control                 *thread_support;
    ISR_Level                          level;

    thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];

    handler_stack = &thread_support->Cancellation_Handlers;

    /*
     * We need interrupts disabled to safely check the chain and pull
     * the last element off.  But we also need dispatching disabled to
     * ensure that we do not get prempted and deleted while we are holding
     * memory that needs to be freed.
     */

    _Thread_Disable_dispatch();
    _ISR_Disable( level );

    if ( _Chain_Is_empty( handler_stack ) ) {
        _Thread_Enable_dispatch();
        _ISR_Enable( level );
        return;
    }

    handler = (POSIX_Cancel_Handler_control *)
              _Chain_Tail( handler_stack )->previous;
    _Chain_Extract_unprotected( &handler->Node );

    _ISR_Enable( level );

    tmp_handler = *handler;

    _Workspace_Free( handler );

    _Thread_Enable_dispatch();

    if ( execute )
        (*tmp_handler.routine)( tmp_handler.arg );
}
Пример #24
0
static void _Scheduler_priority_SMP_Do_extract(
  Scheduler_SMP_Control *self,
  Thread_Control *thread
)
{
  bool is_scheduled = thread->is_scheduled;

  ( void ) self;

  thread->is_in_the_air = is_scheduled;
  thread->is_scheduled = false;

  if ( is_scheduled ) {
    _Chain_Extract_unprotected( &thread->Object.Node );
  } else {
    _Scheduler_priority_Ready_queue_extract( thread );
  }
}
Пример #25
0
void _Scheduler_simple_smp_Extract( Thread_Control *thread )
{
  Scheduler_simple_smp_Control *self = _Scheduler_simple_smp_Instance();

  _Chain_Extract_unprotected( &thread->Object.Node );

  if ( thread->is_scheduled ) {
    Thread_Control *highest_ready =
      (Thread_Control *) _Chain_First( &self->ready );

    _Scheduler_simple_smp_Allocate_processor( highest_ready, thread );

    _Scheduler_simple_smp_Move_from_ready_to_scheduled(
      &self->scheduled,
      highest_ready
    );
  }
}
Пример #26
0
Watchdog_States _Watchdog_Remove(
  Watchdog_Control *the_watchdog
)
{
  ISR_Level         level;
  Watchdog_States   previous_state;
  Watchdog_Control *next_watchdog;

  _ISR_Disable( level );
  previous_state = the_watchdog->state;
  switch ( previous_state ) {
    case WATCHDOG_INACTIVE:
      break;

    case WATCHDOG_BEING_INSERTED:

      /*
       *  It is not actually on the chain so just change the state and
       *  the Insert operation we interrupted will be aborted.
       */
      the_watchdog->state = WATCHDOG_INACTIVE;
      break;

    case WATCHDOG_ACTIVE:
    case WATCHDOG_REMOVE_IT:

      the_watchdog->state = WATCHDOG_INACTIVE;
      next_watchdog = _Watchdog_Next( the_watchdog );

      if ( _Watchdog_Next(next_watchdog) )
        next_watchdog->delta_interval += the_watchdog->delta_interval;

      if ( _Watchdog_Sync_count )
        _Watchdog_Sync_level = _ISR_Nest_level;

      _Chain_Extract_unprotected( &the_watchdog->Node );
      break;
  }
  the_watchdog->stop_time = _Watchdog_Ticks_since_boot;

  _ISR_Enable( level );
  return( previous_state );
}
Пример #27
0
void _Scheduler_simple_Yield(
  const Scheduler_Control *scheduler,
  Thread_Control          *the_thread
)
{
  Scheduler_simple_Context *context =
    _Scheduler_simple_Get_context( scheduler );
  ISR_Level       level;

  _ISR_Disable( level );

    _Chain_Extract_unprotected( &the_thread->Object.Node );
    _Scheduler_simple_Insert_priority_fifo( &context->Ready, the_thread );

    _ISR_Flash( level );

    _Scheduler_simple_Schedule_body( scheduler, the_thread, false );

  _ISR_Enable( level );
}
Пример #28
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
}
void _Thread_Suspend(
  Thread_Control   *the_thread
)
{
  ISR_Level      level;
  Chain_Control *ready;

  ready = the_thread->ready;
  _ISR_Disable( level );
  #if defined(RTEMS_ITRON_API)
    the_thread->suspend_count++;
  #endif
  if ( !_States_Is_ready( the_thread->current_state ) ) {
    the_thread->current_state =
       _States_Set( STATES_SUSPENDED, the_thread->current_state );
    _ISR_Enable( level );
    return;
  }

  the_thread->current_state = STATES_SUSPENDED;

  if ( _Chain_Has_only_one_node( ready ) ) {

    _Chain_Initialize_empty( ready );
    _Priority_Remove_from_bit_map( &the_thread->Priority_map );

  } else
    _Chain_Extract_unprotected( &the_thread->Object.Node );

  _ISR_Flash( level );

  if ( _Thread_Is_heir( the_thread ) )
     _Thread_Calculate_heir();

  if ( _Thread_Is_executing( the_thread ) )
    _Context_Switch_necessary = true;

  _ISR_Enable( level );
}
void _Thread_Set_state(
  Thread_Control *the_thread,
  States_Control  state
)
{
  ISR_Level      level;
  Chain_Control *ready;

  ready = the_thread->ready;
  _ISR_Disable( level );
  if ( !_States_Is_ready( the_thread->current_state ) ) {
    the_thread->current_state =
       _States_Set( state, the_thread->current_state );
    _ISR_Enable( level );
    return;
  }

  the_thread->current_state = state;

  if ( _Chain_Has_only_one_node( ready ) ) {

    _Chain_Initialize_empty( ready );
    _Priority_Remove_from_bit_map( &the_thread->Priority_map );

  } else
    _Chain_Extract_unprotected( &the_thread->Object.Node );

  _ISR_Flash( level );

  if ( _Thread_Is_heir( the_thread ) )
     _Thread_Calculate_heir();

  if ( _Thread_Is_executing( the_thread ) )
    _Context_Switch_necessary = TRUE;

  _ISR_Enable( level );
}