[PATCH] score: Add debug support to chains
Sebastian Huber
sebastian.huber at embedded-brains.de
Thu Jul 21 13:31:32 UTC 2016
This helps to detect
* double insert, append, prepend errors, and
* get from empty chain errors.
---
cpukit/libcsupport/src/malloc_deferred.c | 6 ++-
cpukit/libcsupport/src/mount-mgr.c | 1 +
cpukit/libcsupport/src/printertask.c | 1 +
cpukit/libcsupport/src/sup_fs_location.c | 1 +
cpukit/libcsupport/src/termios.c | 1 +
cpukit/posix/src/aio_misc.c | 4 +-
cpukit/sapi/include/rtems/chain.h | 15 +++++++
cpukit/sapi/include/rtems/rbheap.h | 1 +
cpukit/sapi/src/rbheap.c | 1 +
cpukit/score/include/rtems/score/chainimpl.h | 52 +++++++++++++++++++---
cpukit/score/include/rtems/score/resourceimpl.h | 2 +
.../include/rtems/score/schedulerpriorityimpl.h | 1 +
cpukit/score/include/rtems/score/threadqimpl.h | 1 +
cpukit/score/src/freechain.c | 1 +
cpukit/score/src/objectextendinformation.c | 1 +
cpukit/score/src/threadqops.c | 1 +
testsuites/sptests/spchain/init.c | 36 +++++++++++++--
17 files changed, 115 insertions(+), 11 deletions(-)
diff --git a/cpukit/libcsupport/src/malloc_deferred.c b/cpukit/libcsupport/src/malloc_deferred.c
index 962ae3e..f37b852 100644
--- a/cpukit/libcsupport/src/malloc_deferred.c
+++ b/cpukit/libcsupport/src/malloc_deferred.c
@@ -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
diff --git a/cpukit/libcsupport/src/mount-mgr.c b/cpukit/libcsupport/src/mount-mgr.c
index 20c900f..0246820 100644
--- a/cpukit/libcsupport/src/mount-mgr.c
+++ b/cpukit/libcsupport/src/mount-mgr.c
@@ -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();
diff --git a/cpukit/libcsupport/src/printertask.c b/cpukit/libcsupport/src/printertask.c
index f358f32..bae623b 100644
--- a/cpukit/libcsupport/src/printertask.c
+++ b/cpukit/libcsupport/src/printertask.c
@@ -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();
diff --git a/cpukit/libcsupport/src/sup_fs_location.c b/cpukit/libcsupport/src/sup_fs_location.c
index ddda4d1..2b8126e 100644
--- a/cpukit/libcsupport/src/sup_fs_location.c
+++ b/cpukit/libcsupport/src/sup_fs_location.c
@@ -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;
diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
index d12f9c4..d9886f4 100644
--- a/cpukit/libcsupport/src/termios.c
+++ b/cpukit/libcsupport/src/termios.c
@@ -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;
diff --git a/cpukit/posix/src/aio_misc.c b/cpukit/posix/src/aio_misc.c
index bdcd0d3..5a281a9 100644
--- a/cpukit/posix/src/aio_misc.c
+++ b/cpukit/posix/src/aio_misc.c
@@ -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;
diff --git a/cpukit/sapi/include/rtems/chain.h b/cpukit/sapi/include/rtems/chain.h
index 3d8a860..25f02c9 100644
--- a/cpukit/sapi/include/rtems/chain.h
+++ b/cpukit/sapi/include/rtems/chain.h
@@ -188,6 +188,21 @@ RTEMS_INLINE_ROUTINE void rtems_chain_set_off_chain(
}
/**
+ * @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.
*
* This function returns true if the @a node is not on a chain. A @a node is
diff --git a/cpukit/sapi/include/rtems/rbheap.h b/cpukit/sapi/include/rtems/rbheap.h
index c008721..735aa6c 100644
--- a/cpukit/sapi/include/rtems/rbheap.h
+++ b/cpukit/sapi/include/rtems/rbheap.h
@@ -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);
}
diff --git a/cpukit/sapi/src/rbheap.c b/cpukit/sapi/src/rbheap.c
index 6fc2aef..3a69837 100644
--- a/cpukit/sapi/src/rbheap.c
+++ b/cpukit/sapi/src/rbheap.c
@@ -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);
}
diff --git a/cpukit/score/include/rtems/score/chainimpl.h b/cpukit/score/include/rtems/score/chainimpl.h
index f78f2d6..b50f4ff 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 69e9a3c..4739bda 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 e33866e..38f9f5b 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 73d4de2..df0c3e0 100644
--- a/cpukit/score/include/rtems/score/threadqimpl.h
+++ b/cpukit/score/include/rtems/score/threadqimpl.h
@@ -127,6 +127,7 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Heads_initialize(
#endif
_Chain_Initialize_empty( &heads->Free_chain );
+ _Chain_Initialize_node( &heads->Free_node );
}
RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_initialize(
diff --git a/cpukit/score/src/freechain.c b/cpukit/score/src/freechain.c
index 301e9b2..68786b1 100644
--- a/cpukit/score/src/freechain.c
+++ b/cpukit/score/src/freechain.c
@@ -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 );
}
}
diff --git a/cpukit/score/src/objectextendinformation.c b/cpukit/score/src/objectextendinformation.c
index 2a76114..cd78a72 100644
--- a/cpukit/score/src/objectextendinformation.c
+++ b/cpukit/score/src/objectextendinformation.c
@@ -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 *)
diff --git a/cpukit/score/src/threadqops.c b/cpukit/score/src/threadqops.c
index c3221b9..5a00ee6 100644
--- a/cpukit/score/src/threadqops.c
+++ b/cpukit/score/src/threadqops.c
@@ -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
diff --git a/testsuites/sptests/spchain/init.c b/testsuites/sptests/spchain/init.c
index dd46d68..eb5ea4e 100644
--- a/testsuites/sptests/spchain/init.c
+++ b/testsuites/sptests/spchain/init.c
@@ -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" );
--
1.8.4.5
More information about the devel
mailing list