summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-01-04 09:55:59 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-01-04 10:23:20 +0100
commita061f9d3c5c8da087199e7a6c607648b16f48b15 (patch)
treed28ef250e9f506d19e108861fdce6ccdb8d0595f
parentsptests/sp07: Fix test case (diff)
downloadrtems-a061f9d3c5c8da087199e7a6c607648b16f48b15.tar.bz2
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.
-rw-r--r--cpukit/score/src/watchdoginsert.c16
-rw-r--r--testsuites/sptests/spwatchdog/init.c48
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 );