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 ); }
void _Chain_Insert( Chain_Node *after_node, Chain_Node *node ) { _Chain_Insert_unprotected( after_node, node ); }
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 ); }
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 ); } }
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 ); }
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 ); }
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 ); }
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 ); }
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( ® ); _Chain_Iterator_initialize( &chain, ®, &fit, CHAIN_ITERATOR_FORWARD ); _Chain_Iterator_initialize( &chain, ®, &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( ®, &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( ®, &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( ®, &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( ®, &a ); rtems_test_assert( _Chain_Iterator_next( &fit ) == &b ); rtems_test_assert( _Chain_Iterator_next( &bit ) == &c ); update_registry_and_extract( ®, &b ); rtems_test_assert( _Chain_Iterator_next( &fit ) == &c ); rtems_test_assert( _Chain_Iterator_next( &bit ) == &c ); update_registry_and_extract( ®, &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( ®, &c ); rtems_test_assert( _Chain_Iterator_next( &fit ) == &a ); rtems_test_assert( _Chain_Iterator_next( &bit ) == &b ); update_registry_and_extract( ®, &b ); rtems_test_assert( _Chain_Iterator_next( &fit ) == &a ); rtems_test_assert( _Chain_Iterator_next( &bit ) == &a ); update_registry_and_extract( ®, &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( ®.Iterators )); _Chain_Iterator_destroy( &fit ); rtems_test_assert( !_Chain_Is_empty( ®.Iterators )); _Chain_Iterator_destroy( &bit ); rtems_test_assert( _Chain_Is_empty( ®.Iterators )); }