[rtems commit] score: Fix watchdog insert

Sebastian Huber sebh at rtems.org
Tue Jan 5 06:10:28 UTC 2016


Module:    rtems
Branch:    4.11
Commit:    9c615b7835f397698e0b8c41fa598180cee8ce7a
Changeset: http://git.rtems.org/rtems/commit/?id=9c615b7835f397698e0b8c41fa598180cee8ce7a

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Jan  4 09:55:59 2016 +0100

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 6b81c7b..db15f55 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 d99c558..025295b 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 );
 




More information about the vc mailing list