void _Scheduler_simple_Ready_queue_enqueue_first(
  Thread_Control    *the_thread
)
{
  Chain_Control    *ready;
  Chain_Node       *the_node;
  Thread_Control   *current;

  ready    = (Chain_Control *)_Scheduler.information;
  current  = (Thread_Control *)ready;

  /*
   * Do NOT need to check for end of chain because there is always
   * at least one task on the ready chain -- the IDLE task.  It can
   * never block, should never attempt to obtain a semaphore or mutex,
   * and thus will always be there.
   */
  for ( the_node = _Chain_First(ready) ; ; the_node = the_node->next ) {
    current = (Thread_Control *) the_node;

    /* break when AT HEAD OF (or PAST) our priority */
    if ( the_thread->current_priority <= current->current_priority ) {
      current = (Thread_Control *)current->Object.Node.previous;
      break;
    }
  }

  /* enqueue */
  _Chain_Insert_unprotected( (Chain_Node *)current, &the_thread->Object.Node );
}
Esempio n. 2
0
void _Chain_Insert(
  Chain_Node *after_node,
  Chain_Node *node
)
{
    _Chain_Insert_unprotected( after_node, node );
}
Esempio n. 3
0
void rtems_chain_insert( rtems_chain_node *after_node, rtems_chain_node *node )
{
  rtems_interrupt_lock_context lock_context;

  chain_acquire( &lock_context );
  _Chain_Insert_unprotected( after_node, node );
  chain_release( &lock_context );
}
Esempio n. 4
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 );
  }
}
Esempio n. 5
0
void _Chain_Insert(
    Chain_Node *after_node,
    Chain_Node *node
)
{
    ISR_Level level;

    _ISR_Disable( level );
    _Chain_Insert_unprotected( after_node, node );
    _ISR_Enable( level );
}
Esempio n. 6
0
void rtems_chain_explicit_insert(
    rtems_chain_control *chain,
    rtems_chain_node *after_node,
    rtems_chain_node *node
)
{
    ISR_Level level;

    _ISR_lock_ISR_disable_and_acquire( &chain->Lock, level );
    _Chain_Insert_unprotected( after_node, node );
    _ISR_lock_Release_and_ISR_enable( &chain->Lock, level );
}
Esempio n. 7
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
)
{
  ISR_Level  level;
  #if defined(RTEMS_SCORE_COREMSG_ENABLE_NOTIFICATION)
    bool    notify = false;
    #define SET_NOTIFY() \
      do { \
        if ( the_message_queue->number_of_pending_messages == 0 ) \
          notify = true; \
      } while (0)
  #else
    #define SET_NOTIFY()
  #endif

  _CORE_message_queue_Set_message_priority( the_message, submit_type );

  #if !defined(RTEMS_SCORE_COREMSG_ENABLE_MESSAGE_PRIORITY)
    _ISR_Disable( level );
      SET_NOTIFY();
      the_message_queue->number_of_pending_messages++;
      if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST )
        _CORE_message_queue_Append_unprotected(the_message_queue, the_message);
      else
        _CORE_message_queue_Prepend_unprotected(the_message_queue, the_message);
    _ISR_Enable( level );
  #else
    if ( submit_type == CORE_MESSAGE_QUEUE_SEND_REQUEST ) {
      _ISR_Disable( level );
        SET_NOTIFY();
        the_message_queue->number_of_pending_messages++;
        _CORE_message_queue_Append_unprotected(the_message_queue, the_message);
      _ISR_Enable( level );
    } else if ( submit_type == CORE_MESSAGE_QUEUE_URGENT_REQUEST ) {
      _ISR_Disable( level );
        SET_NOTIFY();
        the_message_queue->number_of_pending_messages++;
        _CORE_message_queue_Prepend_unprotected(the_message_queue, the_message);
      _ISR_Enable( level );
    } else {
      CORE_message_queue_Buffer_control *this_message;
      Chain_Node                        *the_node;
      Chain_Control                     *the_header;
      int                                the_priority;

      the_priority = _CORE_message_queue_Get_message_priority(the_message);
      the_header = &the_message_queue->Pending_messages;
      the_node = _Chain_First( the_header );
      while ( !_Chain_Is_tail( the_header, the_node ) ) {
        int this_priority;

        this_message = (CORE_message_queue_Buffer_control *) the_node;

        this_priority = _CORE_message_queue_Get_message_priority(this_message);

        if ( this_priority <= the_priority ) {
          the_node = the_node->next;
          continue;
        }
        break;
      }
      _ISR_Disable( level );
        SET_NOTIFY();
        the_message_queue->number_of_pending_messages++;
        _Chain_Insert_unprotected( the_node->previous, &the_message->Node );
      _ISR_Enable( level );
    }
  #endif

  #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
}
void _Watchdog_Insert(
  Chain_Control         *header,
  Watchdog_Control      *the_watchdog
)
{
  ISR_Level          level;
  Watchdog_Control  *after;
  uint32_t           insert_isr_nest_level;
  Watchdog_Interval  delta_interval;


  insert_isr_nest_level   = _ISR_Nest_level;

  _ISR_Disable( level );

  /*
   *  Check to see if the watchdog has just been inserted by a
   *  higher priority interrupt.  If so, abandon this insert.
   */

  if ( the_watchdog->state != WATCHDOG_INACTIVE ) {
    _ISR_Enable( level );
    return;
  }

  the_watchdog->state = WATCHDOG_BEING_INSERTED;
  _Watchdog_Sync_count++;

restart:
  delta_interval = the_watchdog->initial;

  /*
   * We CANT use _Watchdog_First() here, because a TICK interrupt
   * could modify the chain during the _ISR_Flash() below. Hence,
   * the header is pointing to volatile data. The _Watchdog_First()
   * INLINE routine (but not the macro - note the subtle difference)
   * casts away the 'volatile'...
   *
   * Also, this is only necessary because we call no other routine
   * from this piece of code, hence the compiler thinks it's safe to
   * cache *header!!
   *
   *  Till Straumann, 7/2003 (gcc-3.2.2 -O4 on powerpc)
   *
   */
  for ( after = (Watchdog_Control *) ((volatile Chain_Control *)header)->first ;
        ;
        after = _Watchdog_Next( after ) ) {

     if ( delta_interval == 0 || !_Watchdog_Next( after ) )
       break;

     if ( delta_interval < after->delta_interval ) {
       after->delta_interval -= delta_interval;
       break;
     }

     delta_interval -= after->delta_interval;

     /*
      *  If you experience problems comment out the _ISR_Flash line.
      *  3.2.0 was the first release with this critical section redesigned.
      *  Under certain circumstances, the PREVIOUS critical section algorithm
      *  used around this flash point allowed interrupts to execute
      *  which violated the design assumptions.  The critical section
      *  mechanism used here WAS redesigned to address this.
      */

     _ISR_Flash( level );

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

     if ( _Watchdog_Sync_level > insert_isr_nest_level ) {
       _Watchdog_Sync_level = insert_isr_nest_level;
       goto restart;
     }
  }

  _Watchdog_Activate( the_watchdog );

  the_watchdog->delta_interval = delta_interval;

  _Chain_Insert_unprotected( after->Node.previous, &the_watchdog->Node );

  the_watchdog->start_time = _Watchdog_Ticks_since_boot;

exit_insert:
  _Watchdog_Sync_level = insert_isr_nest_level;
  _Watchdog_Sync_count--;
  _ISR_Enable( level );
}
Esempio n. 9
0
void _Watchdog_Insert(
  Watchdog_Header       *header,
  Watchdog_Control      *the_watchdog
)
{
  ISR_Level          level;
  Watchdog_Control  *after;
  uint32_t           insert_isr_nest_level;
  Watchdog_Interval  delta_interval;


  insert_isr_nest_level   = _ISR_Nest_level;

  _ISR_Disable( level );

  /*
   *  Check to see if the watchdog has just been inserted by a
   *  higher priority interrupt.  If so, abandon this insert.
   */

  if ( the_watchdog->state != WATCHDOG_INACTIVE ) {
    _ISR_Enable( level );
    return;
  }

  the_watchdog->state = WATCHDOG_BEING_INSERTED;
  _Watchdog_Sync_count++;

restart:
  delta_interval = the_watchdog->initial;

  for ( after = _Watchdog_First( header ) ;
        ;
        after = _Watchdog_Next( after ) ) {

     if ( delta_interval == 0 || !_Watchdog_Next( after ) )
       break;

     if ( delta_interval < after->delta_interval ) {
       after->delta_interval -= delta_interval;
       break;
     }

     delta_interval -= after->delta_interval;

     _ISR_Flash( level );

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

     if ( _Watchdog_Sync_level > insert_isr_nest_level ) {
       _Watchdog_Sync_level = insert_isr_nest_level;
       goto restart;
     }
  }

  _Watchdog_Activate( the_watchdog );

  the_watchdog->delta_interval = delta_interval;

  _Chain_Insert_unprotected( after->Node.previous, &the_watchdog->Node );

  the_watchdog->start_time = _Watchdog_Ticks_since_boot;

exit_insert:
  _Watchdog_Sync_level = insert_isr_nest_level;
  _Watchdog_Sync_count--;
  _ISR_Enable( level );
}
Esempio n. 10
0
File: init.c Progetto: Dipupo/rtems
static void test_chain_iterator( void )
{
  Chain_Control chain;
  Chain_Iterator_registry reg;
  Chain_Iterator fit;
  Chain_Iterator bit;
  Chain_Node a;
  Chain_Node b;
  Chain_Node c;

  puts( "INIT - Verify Chain_Iterator" );

  rtems_test_assert( _Chain_Is_empty( &static_reg.Iterators ));

  _Chain_Initialize_empty( &chain );
  _Chain_Iterator_registry_initialize( &reg );
  _Chain_Iterator_initialize( &chain, &reg, &fit, CHAIN_ITERATOR_FORWARD );
  _Chain_Iterator_initialize( &chain, &reg, &bit, CHAIN_ITERATOR_BACKWARD );

  rtems_test_assert( _Chain_Iterator_next( &fit ) == _Chain_Tail( &chain ));
  rtems_test_assert( _Chain_Iterator_next( &bit ) == _Chain_Head( &chain ));

  _Chain_Iterator_set_position( &fit, _Chain_Head( &chain ) );
  _Chain_Iterator_set_position( &bit, _Chain_Tail( &chain ) );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == _Chain_Tail( &chain ));
  rtems_test_assert( _Chain_Iterator_next( &bit ) == _Chain_Head( &chain ));

  _Chain_Append_unprotected( &chain, &a );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &a );

  _Chain_Append_unprotected( &chain, &b );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &b );

  _Chain_Append_unprotected( &chain, &c );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );

  update_registry_and_extract( &reg, &b );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );

  _Chain_Insert_unprotected( &a, &b );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );

  update_registry_and_extract( &reg, &c );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &b );

  _Chain_Append_unprotected( &chain, &c );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );

  update_registry_and_extract( &reg, &a );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &b );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );

  _Chain_Prepend_unprotected( &chain, &a );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );

  update_registry_and_extract( &reg, &a );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &b );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );

  update_registry_and_extract( &reg, &b );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &c );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );

  update_registry_and_extract( &reg, &c );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == _Chain_Tail( &chain ));
  rtems_test_assert( _Chain_Iterator_next( &bit ) == _Chain_Head( &chain ));

  _Chain_Append_unprotected( &chain, &a );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &a );

  _Chain_Append_unprotected( &chain, &b );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &b );

  _Chain_Append_unprotected( &chain, &c );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &c );

  update_registry_and_extract( &reg, &c );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &b );

  update_registry_and_extract( &reg, &b );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == &a );
  rtems_test_assert( _Chain_Iterator_next( &bit ) == &a );

  update_registry_and_extract( &reg, &a );
  rtems_test_assert( _Chain_Iterator_next( &fit ) == _Chain_Tail( &chain ));
  rtems_test_assert( _Chain_Iterator_next( &bit ) == _Chain_Head( &chain ));

  rtems_test_assert( !_Chain_Is_empty( &reg.Iterators ));
  _Chain_Iterator_destroy( &fit );
  rtems_test_assert( !_Chain_Is_empty( &reg.Iterators ));
  _Chain_Iterator_destroy( &bit );
  rtems_test_assert( _Chain_Is_empty( &reg.Iterators ));
}