diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-07-21 10:15:02 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-07-22 09:13:07 +0200 |
commit | 059529e685e059d366ee56aa6117ee0d4e899e66 (patch) | |
tree | 77255d92003c98d84f558f6dbc27d474a842cf83 /cpukit/score/include | |
parent | posix: Fix double chain extract (diff) | |
download | rtems-059529e685e059d366ee56aa6117ee0d4e899e66.tar.bz2 |
score: Add debug support to chains
This helps to detect
* double insert, append, prepend errors, and
* get from empty chain errors.
Diffstat (limited to 'cpukit/score/include')
4 files changed, 52 insertions, 5 deletions
diff --git a/cpukit/score/include/rtems/score/chainimpl.h b/cpukit/score/include/rtems/score/chainimpl.h index f78f2d60bb..b50f4ff910 100644 --- a/cpukit/score/include/rtems/score/chainimpl.h +++ b/cpukit/score/include/rtems/score/chainimpl.h @@ -104,6 +104,26 @@ RTEMS_INLINE_ROUTINE void _Chain_Set_off_chain( ) { node->next = NULL; +#if defined(RTEMS_DEBUG) + node->previous = NULL; +#endif +} + +/** + * @brief Initializes a chain node. + * + * In debug configurations, the node is set off chain. In all other + * configurations, this function does nothing. + * + * @param[in] the_node The chain node to initialize. + */ +RTEMS_INLINE_ROUTINE void _Chain_Initialize_node( Chain_Node *the_node ) +{ +#if defined(RTEMS_DEBUG) + _Chain_Set_off_chain( the_node ); +#else + (void) the_node; +#endif } /** @@ -519,6 +539,10 @@ RTEMS_INLINE_ROUTINE void _Chain_Extract_unprotected( previous = the_node->previous; next->previous = previous; previous->next = next; + +#if defined(RTEMS_DEBUG) + _Chain_Set_off_chain( the_node ); +#endif } /** @@ -540,13 +564,23 @@ RTEMS_INLINE_ROUTINE Chain_Node *_Chain_Get_first_unprotected( Chain_Control *the_chain ) { - Chain_Node *head = _Chain_Head( the_chain ); - Chain_Node *old_first = head->next; - Chain_Node *new_first = old_first->next; + Chain_Node *head; + Chain_Node *old_first; + Chain_Node *new_first; + + _Assert( !_Chain_Is_empty( the_chain ) ); + + head = _Chain_Head( the_chain ); + old_first = head->next; + new_first = old_first->next; head->next = new_first; new_first->previous = head; +#if defined(RTEMS_DEBUG) + _Chain_Set_off_chain( old_first ); +#endif + return old_first; } @@ -594,6 +628,8 @@ RTEMS_INLINE_ROUTINE void _Chain_Insert_unprotected( { Chain_Node *before_node; + _Assert( _Chain_Is_node_off_chain( the_node ) ); + the_node->previous = after_node; before_node = after_node->next; after_node->next = the_node; @@ -617,8 +653,13 @@ RTEMS_INLINE_ROUTINE void _Chain_Append_unprotected( Chain_Node *the_node ) { - Chain_Node *tail = _Chain_Tail( the_chain ); - Chain_Node *old_last = tail->previous; + Chain_Node *tail; + Chain_Node *old_last; + + _Assert( _Chain_Is_node_off_chain( the_node ) ); + + tail = _Chain_Tail( the_chain ); + old_last = tail->previous; the_node->next = tail; tail->previous = the_node; @@ -978,6 +1019,7 @@ RTEMS_INLINE_ROUTINE void _Chain_Iterator_initialize( Chain_Iterator_direction direction ) { + _Chain_Initialize_node( &the_iterator->Registry_node ); _Chain_Append_unprotected( &the_registry->Iterators, &the_iterator->Registry_node diff --git a/cpukit/score/include/rtems/score/resourceimpl.h b/cpukit/score/include/rtems/score/resourceimpl.h index 69e9a3c5f8..4739bdadba 100644 --- a/cpukit/score/include/rtems/score/resourceimpl.h +++ b/cpukit/score/include/rtems/score/resourceimpl.h @@ -59,6 +59,7 @@ RTEMS_INLINE_ROUTINE void _Resource_Node_initialize( Resource_Node *node ) { node->dependency = NULL; node->root = node; + _Chain_Initialize_node( &node->Node ); _Chain_Initialize_empty( &node->Resources ); } @@ -106,6 +107,7 @@ RTEMS_INLINE_ROUTINE void _Resource_Node_extract( Resource_Node *node ) RTEMS_INLINE_ROUTINE void _Resource_Initialize( Resource_Control *resource ) { resource->owner = NULL; + _Chain_Initialize_node( &resource->Node ); _Chain_Initialize_empty( &resource->Rivals ); } diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h index e33866e59b..38f9f5b53a 100644 --- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h +++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h @@ -131,6 +131,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract( if ( _Chain_Has_only_one_node( ready_chain ) ) { _Chain_Initialize_empty( ready_chain ); + _Chain_Initialize_node( node ); _Priority_bit_map_Remove( bit_map, &ready_queue->Priority_map ); } else { _Chain_Extract_unprotected( node ); diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index 73d4de2032..986edc3482 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -122,11 +122,13 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Heads_initialize( size_t i; for ( i = 0; i < _Scheduler_Count; ++i ) { + _Chain_Initialize_node( &heads->Priority[ i ].Node ); _RBTree_Initialize_empty( &heads->Priority[ i ].Queue ); } #endif _Chain_Initialize_empty( &heads->Free_chain ); + _Chain_Initialize_node( &heads->Free_node ); } RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_initialize( |