summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/watchdoginsert.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/src/watchdoginsert.c')
-rw-r--r--cpukit/score/src/watchdoginsert.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/cpukit/score/src/watchdoginsert.c b/cpukit/score/src/watchdoginsert.c
index 43c1eacd76..0602a0c9b6 100644
--- a/cpukit/score/src/watchdoginsert.c
+++ b/cpukit/score/src/watchdoginsert.c
@@ -38,13 +38,28 @@ void _Watchdog_Insert(
insert_isr_nest_level = _ISR_Nest_level;
the_watchdog->state = WATCHDOG_BEING_INSERTED;
+ _ISR_Disable( level );
+
_Watchdog_Sync_count++;
+
restart:
delta_interval = the_watchdog->initial;
- _ISR_Disable( level );
-
- for ( after = _Watchdog_First( header ) ;
+ /*
+ * We CANT use _Watchdog_First() here, because a TICK interrupt
+ * could modify the chain during the _ISR_Flash() below. Hence,
+ * the header is pointing to volatile data. The _Watchdog_First()
+ * INLINE routine (but not the macro - note the subtle difference)
+ * casts away the 'volatile'...
+ *
+ * Also, this is only necessary because we call no other routine
+ * from this piece of code, hence the compiler thinks it's safe to
+ * cache *header!!
+ *
+ * Till Straumann, 7/2003 (gcc-3.2.2 -O4 on powerpc)
+ *
+ */
+ for ( after = (Watchdog_Control *) ((volatile Chain_Control *)header)->first ;
;
after = _Watchdog_Next( after ) ) {
@@ -75,7 +90,6 @@ restart:
if ( _Watchdog_Sync_level > insert_isr_nest_level ) {
_Watchdog_Sync_level = insert_isr_nest_level;
- _ISR_Enable( level );
goto restart;
}
}