From 9c615b7835f397698e0b8c41fa598180cee8ce7a Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 4 Jan 2016 09:55:59 +0100 Subject: score: Fix watchdog insert Under certain conditions a new watchdog was inserted with a wrong and very large delta interval due to a wrong iterator update. Bug was introduced by 1ccbd052910ed16131c74b0d5595c8a94066942d. Close #2507. --- cpukit/score/src/watchdoginsert.c | 16 +++++++++--- testsuites/sptests/spwatchdog/init.c | 48 +++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/cpukit/score/src/watchdoginsert.c b/cpukit/score/src/watchdoginsert.c index 6b81c7b872..db15f55b0d 100644 --- a/cpukit/score/src/watchdoginsert.c +++ b/cpukit/score/src/watchdoginsert.c @@ -22,14 +22,16 @@ static void _Watchdog_Insert_fixup( Watchdog_Header *header, + Watchdog_Control *the_watchdog, + Watchdog_Interval delta, Watchdog_Control *next_watchdog, - Watchdog_Interval delta + Watchdog_Interval delta_next ) { const Chain_Node *iterator_tail; Chain_Node *iterator_node; - next_watchdog->delta_interval -= delta; + next_watchdog->delta_interval = delta_next - delta; iterator_node = _Chain_First( &header->Iterators ); iterator_tail = _Chain_Immutable_tail( &header->Iterators ); @@ -40,7 +42,7 @@ static void _Watchdog_Insert_fixup( iterator = (Watchdog_Iterator *) iterator_node; if ( iterator->current == &next_watchdog->Node ) { - iterator->delta_interval -= delta; + iterator->current = &the_watchdog->Node; } iterator_node = _Chain_Next( iterator_node ); @@ -76,7 +78,13 @@ void _Watchdog_Insert_locked( delta_next = next_watchdog->delta_interval; if ( delta < delta_next ) { - _Watchdog_Insert_fixup( header, next_watchdog, delta ); + _Watchdog_Insert_fixup( + header, + the_watchdog, + delta, + next_watchdog, + delta_next + ); break; } diff --git a/testsuites/sptests/spwatchdog/init.c b/testsuites/sptests/spwatchdog/init.c index d99c558d43..025295b45b 100644 --- a/testsuites/sptests/spwatchdog/init.c +++ b/testsuites/sptests/spwatchdog/init.c @@ -131,8 +131,8 @@ static void test_watchdog_insert_and_remove( void ) /* Insert right before current watchdog of iterator */ d->initial = 3; _Watchdog_Insert( &header, d ); - rtems_test_assert( i.delta_interval == 1 ); - rtems_test_assert( i.current == &b->Node ); + rtems_test_assert( i.delta_interval == 2 ); + rtems_test_assert( i.current == &d->Node ); destroy_watchdogs( &header ); init_watchdogs( &header, watchdogs ); @@ -192,8 +192,47 @@ static void test_watchdog_remove_second_and_insert_first( void ) _Watchdog_Insert( &header, c ); rtems_test_assert( a->delta_interval == 2 ); rtems_test_assert( c->delta_interval == 4 ); - rtems_test_assert( i.delta_interval == 4 ); - rtems_test_assert( i.current == &a->Node ); + rtems_test_assert( i.delta_interval == 8 ); + rtems_test_assert( i.current == &c->Node ); + + destroy_watchdogs( &header ); +} + +static void init_watchdogs_insert_with_iterator( + Watchdog_Header *header, + Watchdog_Control watchdogs[2] +) +{ + Watchdog_Control *a = &watchdogs[0]; + Watchdog_Control *b = &watchdogs[1]; + + _Watchdog_Preinitialize( a ); + _Watchdog_Preinitialize( b ); + + _Watchdog_Header_initialize( header ); + + a->initial = 6; + _Watchdog_Insert( header, a ); + rtems_test_assert( a->delta_interval == 6 ); +} + +static void test_watchdog_insert_with_iterator( void ) +{ + Watchdog_Header header; + Watchdog_Control watchdogs[2]; + Watchdog_Control *a = &watchdogs[0]; + Watchdog_Control *b = &watchdogs[1]; + Watchdog_Iterator i; + + init_watchdogs_insert_with_iterator( &header, watchdogs ); + add_iterator( &header, &i, a ); + + b->initial = 4; + _Watchdog_Insert( &header, b ); + rtems_test_assert( a->delta_interval == 2 ); + rtems_test_assert( b->delta_interval == 4 ); + rtems_test_assert( i.delta_interval == 2 ); + rtems_test_assert( i.current == &b->Node ); destroy_watchdogs( &header ); } @@ -236,6 +275,7 @@ rtems_task Init( test_watchdog_static_init(); test_watchdog_insert_and_remove(); test_watchdog_remove_second_and_insert_first(); + test_watchdog_insert_with_iterator(); build_time( &time, 12, 31, 1988, 9, 0, 0, 0 ); -- cgit v1.2.3