forked from Imagelibrary/rtems
score: Add debug support to chains
This helps to detect * double insert, append, prepend errors, and * get from empty chain errors.
This commit is contained in:
@@ -127,9 +127,13 @@ void *rtems_heap_allocate_aligned_with_boundary(
|
||||
void _Malloc_Deferred_free( void *p )
|
||||
{
|
||||
rtems_interrupt_lock_context lock_context;
|
||||
rtems_chain_node *node;
|
||||
|
||||
node = (rtems_chain_node *) p;
|
||||
|
||||
rtems_interrupt_lock_acquire( &_Malloc_GC_lock, &lock_context );
|
||||
rtems_chain_append_unprotected( &_Malloc_GC_list, (rtems_chain_node *) p );
|
||||
rtems_chain_initialize_node( node );
|
||||
rtems_chain_append_unprotected( &_Malloc_GC_list, node );
|
||||
rtems_interrupt_lock_release( &_Malloc_GC_lock, &lock_context );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -124,6 +124,7 @@ rtems_filesystem_register(
|
||||
|
||||
rtems_libio_lock();
|
||||
if ( rtems_filesystem_get_mount_handler( type ) == NULL ) {
|
||||
rtems_chain_initialize_node( &fsn->node );
|
||||
rtems_chain_append_unprotected( chain, &fsn->node );
|
||||
} else {
|
||||
rtems_libio_unlock();
|
||||
|
||||
@@ -194,6 +194,7 @@ void rtems_printer_task_drain( rtems_printer_task_context *ctx )
|
||||
{
|
||||
printer_task_buffer buffer;
|
||||
|
||||
rtems_chain_initialize_node( &buffer.node );
|
||||
buffer.action_kind = ACTION_DRAIN;
|
||||
buffer.action_data.task = rtems_task_self();
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ rtems_filesystem_location_info_t *rtems_filesystem_location_copy(
|
||||
dst->node_access_2 = src->node_access_2;
|
||||
dst->handlers = src->handlers;
|
||||
dst->mt_entry = src->mt_entry;
|
||||
rtems_chain_initialize_node(&dst->mt_entry_node);
|
||||
rtems_filesystem_location_add_to_mt_entry(dst);
|
||||
|
||||
return dst;
|
||||
|
||||
@@ -149,6 +149,7 @@ rtems_status_code rtems_termios_device_install(
|
||||
return RTEMS_NO_MEMORY;
|
||||
}
|
||||
|
||||
rtems_chain_initialize_node(&new_device_node->node);
|
||||
new_device_node->major = major;
|
||||
new_device_node->minor = minor;
|
||||
new_device_node->handler = handler;
|
||||
|
||||
@@ -116,6 +116,7 @@ rtems_aio_search_fd (rtems_chain_control *chain, int fildes, int create)
|
||||
else {
|
||||
r_chain = malloc (sizeof (rtems_aio_request_chain));
|
||||
rtems_chain_initialize_empty (&r_chain->perfd);
|
||||
rtems_chain_initialize_node (&r_chain->next_fd);
|
||||
|
||||
if (rtems_chain_is_empty (chain))
|
||||
rtems_chain_prepend (chain, &r_chain->next_fd);
|
||||
@@ -222,9 +223,9 @@ void rtems_aio_remove_fd (rtems_aio_request_chain *r_chain)
|
||||
|
||||
while (!rtems_chain_is_tail (chain, node))
|
||||
{
|
||||
rtems_chain_extract (node);
|
||||
rtems_aio_request *req = (rtems_aio_request *) node;
|
||||
node = rtems_chain_next (node);
|
||||
rtems_chain_extract (&req->next_prio);
|
||||
req->aiocbp->error_code = ECANCELED;
|
||||
req->aiocbp->return_value = -1;
|
||||
free (req);
|
||||
@@ -311,6 +312,7 @@ rtems_aio_enqueue (rtems_aio_request *req)
|
||||
we can use aio_reqprio to lower the priority of the request */
|
||||
pthread_getschedparam (pthread_self(), &policy, ¶m);
|
||||
|
||||
rtems_chain_initialize_node (&req->next_prio);
|
||||
req->caller_thread = pthread_self ();
|
||||
req->priority = param.sched_priority - req->aiocbp->aio_reqprio;
|
||||
req->policy = policy;
|
||||
|
||||
@@ -187,6 +187,21 @@ RTEMS_INLINE_ROUTINE void rtems_chain_set_off_chain(
|
||||
_Chain_Set_off_chain( node );
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 rtems_chain_initialize_node(
|
||||
rtems_chain_node *node
|
||||
)
|
||||
{
|
||||
_Chain_Initialize_node( node );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Is the node off chain.
|
||||
*
|
||||
|
||||
@@ -210,6 +210,7 @@ static inline void rtems_rbheap_add_to_spare_descriptor_chain(
|
||||
rtems_chain_control *chain =
|
||||
rtems_rbheap_get_spare_descriptor_chain(control);
|
||||
|
||||
rtems_chain_initialize_node(&chunk->chain_node);
|
||||
rtems_chain_prepend_unprotected(chain, &chunk->chain_node);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ static void add_to_chain(
|
||||
rtems_rbheap_chunk *chunk
|
||||
)
|
||||
{
|
||||
rtems_chain_initialize_node(&chunk->chain_node);
|
||||
rtems_chain_prepend_unprotected(chain, &chunk->chain_node);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -75,6 +75,7 @@ void *_Freechain_Get(
|
||||
void _Freechain_Put( Freechain_Control *freechain, void *node )
|
||||
{
|
||||
if ( node != NULL ) {
|
||||
_Chain_Initialize_node( node );
|
||||
_Chain_Prepend_unprotected( &freechain->Free, node );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,6 +265,7 @@ void _Objects_Extend_information(
|
||||
index
|
||||
);
|
||||
|
||||
_Chain_Initialize_node( &the_object->Node );
|
||||
_Chain_Append_unprotected( &information->Inactive, &the_object->Node );
|
||||
|
||||
the_object = (Objects_Control *)
|
||||
|
||||
@@ -99,6 +99,7 @@ static void _Thread_queue_FIFO_do_enqueue(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
_Chain_Initialize_node( &the_thread->Wait.Node.Chain );
|
||||
_Chain_Append_unprotected(
|
||||
&heads->Heads.Fifo,
|
||||
&the_thread->Wait.Node.Chain
|
||||
|
||||
@@ -43,6 +43,9 @@ static void test_chain_iterator( void )
|
||||
rtems_test_assert( _Chain_Is_empty( &static_reg.Iterators ));
|
||||
|
||||
_Chain_Initialize_empty( &chain );
|
||||
_Chain_Initialize_node( &a );
|
||||
_Chain_Initialize_node( &b );
|
||||
_Chain_Initialize_node( &c );
|
||||
_Chain_Iterator_registry_initialize( ® );
|
||||
_Chain_Iterator_initialize( &chain, ®, &fit, CHAIN_ITERATOR_FORWARD );
|
||||
_Chain_Iterator_initialize( &chain, ®, &bit, CHAIN_ITERATOR_BACKWARD );
|
||||
@@ -225,6 +228,8 @@ static void test_chain_first_and_last(void)
|
||||
rtems_chain_node *cnode;
|
||||
|
||||
rtems_chain_initialize_empty( &chain );
|
||||
rtems_chain_initialize_node( &node1 );
|
||||
rtems_chain_initialize_node( &node2 );
|
||||
rtems_chain_append( &chain, &node1 );
|
||||
rtems_chain_insert( &node1, &node2 );
|
||||
|
||||
@@ -255,6 +260,7 @@ static void test_chain_with_notification(void)
|
||||
|
||||
puts( "INIT - Verify rtems_chain_append_with_notification" );
|
||||
rtems_chain_initialize_empty( &chain );
|
||||
rtems_chain_initialize_node( &a );
|
||||
sc = rtems_chain_append_with_notification(
|
||||
&chain,
|
||||
&a,
|
||||
@@ -267,6 +273,8 @@ static void test_chain_with_notification(void)
|
||||
rtems_test_assert( p == &a );
|
||||
|
||||
rtems_chain_initialize_empty( &chain );
|
||||
rtems_chain_initialize_node( &a );
|
||||
rtems_chain_initialize_node( &b );
|
||||
|
||||
rtems_chain_append( &chain, &b );
|
||||
sc = rtems_chain_append_with_notification(
|
||||
@@ -280,6 +288,8 @@ static void test_chain_with_notification(void)
|
||||
|
||||
puts( "INIT - Verify rtems_chain_prepend_with_notification" );
|
||||
rtems_chain_initialize_empty( &chain );
|
||||
rtems_chain_initialize_node( &a );
|
||||
rtems_chain_initialize_node( &b );
|
||||
sc = rtems_chain_prepend_with_notification(
|
||||
&chain,
|
||||
&a,
|
||||
@@ -303,6 +313,8 @@ static void test_chain_with_notification(void)
|
||||
|
||||
puts( "INIT - Verify rtems_chain_get_with_notification" );
|
||||
rtems_chain_initialize_empty( &chain );
|
||||
rtems_chain_initialize_node( &a );
|
||||
rtems_chain_initialize_node( &b );
|
||||
|
||||
rtems_chain_append( &chain, &b );
|
||||
rtems_chain_append( &chain, &a );
|
||||
@@ -329,27 +341,35 @@ static void test_chain_with_empty_check(void)
|
||||
rtems_chain_control chain;
|
||||
rtems_chain_node a;
|
||||
rtems_chain_node b;
|
||||
rtems_chain_node c;
|
||||
rtems_chain_node *p;
|
||||
bool empty;
|
||||
|
||||
puts( "INIT - Verify rtems_chain_append_with_empty_check" );
|
||||
rtems_chain_initialize_empty( &chain );
|
||||
rtems_chain_initialize_node( &a );
|
||||
rtems_chain_initialize_node( &b );
|
||||
empty = rtems_chain_append_with_empty_check( &chain, &a );
|
||||
rtems_test_assert( empty );
|
||||
empty = rtems_chain_append_with_empty_check( &chain, &a );
|
||||
empty = rtems_chain_append_with_empty_check( &chain, &b );
|
||||
rtems_test_assert( !empty );
|
||||
|
||||
puts( "INIT - Verify rtems_chain_prepend_with_empty_check" );
|
||||
rtems_chain_initialize_empty( &chain );
|
||||
rtems_chain_initialize_node( &a );
|
||||
rtems_chain_initialize_node( &b );
|
||||
rtems_chain_initialize_node( &c );
|
||||
empty = rtems_chain_prepend_with_empty_check( &chain, &a );
|
||||
rtems_test_assert( empty );
|
||||
empty = rtems_chain_prepend_with_empty_check( &chain, &a );
|
||||
rtems_test_assert( !empty );
|
||||
empty = rtems_chain_prepend_with_empty_check( &chain, &b );
|
||||
rtems_test_assert( !empty );
|
||||
empty = rtems_chain_prepend_with_empty_check( &chain, &c );
|
||||
rtems_test_assert( !empty );
|
||||
|
||||
puts( "INIT - Verify rtems_chain_get_with_empty_check" );
|
||||
rtems_chain_initialize_empty( &chain );
|
||||
rtems_chain_initialize_node( &a );
|
||||
rtems_chain_initialize_node( &b );
|
||||
empty = rtems_chain_get_with_empty_check( &chain, &p );
|
||||
rtems_test_assert( empty );
|
||||
|
||||
@@ -377,6 +397,7 @@ static void test_chain_node_count(void)
|
||||
rtems_test_assert( count == 0 );
|
||||
|
||||
for (i = 0; i < RTEMS_ARRAY_SIZE( nodes ); ++i) {
|
||||
rtems_chain_initialize_node( &nodes[ i ] );
|
||||
rtems_chain_append_unprotected( &chain, &nodes[i] );
|
||||
count = rtems_chain_node_count_unprotected( &chain );
|
||||
rtems_test_assert( count == i + 1 );
|
||||
@@ -395,10 +416,14 @@ static void test_chain_insert_ordered( void )
|
||||
const Chain_Node *tail;
|
||||
const Chain_Node *node;
|
||||
size_t n = RTEMS_ARRAY_SIZE( nodes );
|
||||
size_t i = 0;
|
||||
size_t i;
|
||||
|
||||
puts( "INIT - Verify _Chain_Insert_ordered_unprotected" );
|
||||
|
||||
for ( i = 0; i < n; ++i ) {
|
||||
_Chain_Initialize_node( &nodes[ i ] );
|
||||
}
|
||||
|
||||
_Chain_Insert_ordered_unprotected( &chain, &nodes[4], test_order );
|
||||
_Chain_Insert_ordered_unprotected( &chain, &nodes[2], test_order );
|
||||
_Chain_Insert_ordered_unprotected( &chain, &nodes[0], test_order );
|
||||
@@ -407,6 +432,7 @@ static void test_chain_insert_ordered( void )
|
||||
|
||||
tail = _Chain_Immutable_tail( &chain );
|
||||
node = _Chain_Immutable_first( &chain );
|
||||
i = 0;
|
||||
while ( node != tail && i < n ) {
|
||||
rtems_test_assert( node == &nodes[ i ] );
|
||||
++i;
|
||||
@@ -429,6 +455,8 @@ rtems_task Init(
|
||||
|
||||
puts( "Init - Initialize chain empty" );
|
||||
rtems_chain_initialize_empty( &chain1 );
|
||||
rtems_chain_initialize_node( &node1.Node );
|
||||
rtems_chain_initialize_node( &node2.Node );
|
||||
|
||||
/* verify that the chain append and insert work */
|
||||
puts( "INIT - Verify rtems_chain_insert" );
|
||||
|
||||
Reference in New Issue
Block a user