diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2005-08-17 22:50:30 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2005-08-17 22:50:30 +0000 |
commit | f45e8840c81f5534e0d2a998f271024bd213d607 (patch) | |
tree | 94e91af6b3415391c804de77f26a11c34799a168 | |
parent | 2005-08-17 Nickolay Semyonov <snob@oktetlabs.ru> (diff) | |
download | rtems-f45e8840c81f5534e0d2a998f271024bd213d607.tar.bz2 |
2005-08-17 Andrew Sinclair <Andrew.Sinclair@elprotech.com>
PR 807/rtems
* rtems/src/timerfireafter.c, rtems/src/timerserverfireafter.c,
score/src/watchdoginsert.c: Tighten critical section checks on an ISR
using the same timer being inserted by a lower priority ISR or
interupt task.
-rw-r--r-- | cpukit/rtems/ChangeLog | 8 | ||||
-rw-r--r-- | cpukit/rtems/src/timerfireafter.c | 26 | ||||
-rw-r--r-- | cpukit/rtems/src/timerserverfireafter.c | 26 | ||||
-rw-r--r-- | cpukit/score/ChangeLog | 8 | ||||
-rw-r--r-- | cpukit/score/src/watchdoginsert.c | 12 |
5 files changed, 74 insertions, 6 deletions
diff --git a/cpukit/rtems/ChangeLog b/cpukit/rtems/ChangeLog index fde6efd0f5..7cfb6f3fc7 100644 --- a/cpukit/rtems/ChangeLog +++ b/cpukit/rtems/ChangeLog @@ -1,3 +1,11 @@ +2005-08-17 Andrew Sinclair <Andrew.Sinclair@elprotech.com> + + PR 807/rtems + * rtems/src/timerfireafter.c, rtems/src/timerserverfireafter.c, + score/src/watchdoginsert.c: Tighten critical section checks on an ISR + using the same timer being inserted by a lower priority ISR or + interupt task. + 2005-05-13 Jennifer Averett <jennifer.averett@oarcorp.com> PR 786/rtems diff --git a/cpukit/rtems/src/timerfireafter.c b/cpukit/rtems/src/timerfireafter.c index 7b4660c82b..76b426b107 100644 --- a/cpukit/rtems/src/timerfireafter.c +++ b/cpukit/rtems/src/timerfireafter.c @@ -47,6 +47,7 @@ rtems_status_code rtems_timer_fire_after( { Timer_Control *the_timer; Objects_Locations location; + ISR_Level level; if ( ticks == 0 ) return RTEMS_INVALID_NUMBER; @@ -64,8 +65,29 @@ rtems_status_code rtems_timer_fire_after( case OBJECTS_LOCAL: (void) _Watchdog_Remove( &the_timer->Ticker ); - the_timer->the_class = TIMER_INTERVAL; - _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); + + _ISR_Disable( level ); + + /* + * Check to see if the watchdog has just been inserted by a + * higher priority interrupt. If so, abandon this insert. + */ + + if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) { + _ISR_Enable( level ); + return RTEMS_SUCCESSFUL; + } + + /* + * OK. Now we now the timer was not rescheduled by an interrupt + * so we can atomically initialize it as in use. + */ + + the_timer->the_class = TIMER_INTERVAL; + _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); + _ISR_Enable( level ); + + _Watchdog_Insert_ticks( &the_timer->Ticker, ticks ); _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; diff --git a/cpukit/rtems/src/timerserverfireafter.c b/cpukit/rtems/src/timerserverfireafter.c index 0074ea4c0c..eff74b49cc 100644 --- a/cpukit/rtems/src/timerserverfireafter.c +++ b/cpukit/rtems/src/timerserverfireafter.c @@ -48,6 +48,7 @@ rtems_status_code rtems_timer_server_fire_after( { Timer_Control *the_timer; Objects_Locations location; + ISR_Level level; extern Chain_Control _Timer_Ticks_chain; if ( !_Timer_Server ) @@ -69,9 +70,28 @@ rtems_status_code rtems_timer_server_fire_after( case OBJECTS_LOCAL: (void) _Watchdog_Remove( &the_timer->Ticker ); - the_timer->the_class = TIMER_INTERVAL_ON_TASK; - _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); - the_timer->Ticker.initial = ticks; + + _ISR_Disable( level ); + + /* + * Check to see if the watchdog has just been inserted by a + * higher priority interrupt. If so, abandon this insert. + */ + + if ( the_timer->Ticker.state != WATCHDOG_INACTIVE ) { + _ISR_Enable( level ); + return RTEMS_SUCCESSFUL; + } + + /* + * OK. Now we now the timer was not rescheduled by an interrupt + * so we can atomically initialize it as in use. + */ + + the_timer->the_class = TIMER_INTERVAL_ON_TASK; + _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); + the_timer->Ticker.initial = ticks; + _ISR_Enable( level ); _Timer_Server_stop_ticks_timer(); _Timer_Server_process_ticks_chain(); diff --git a/cpukit/score/ChangeLog b/cpukit/score/ChangeLog index f1fe0f362c..19ada3cc3e 100644 --- a/cpukit/score/ChangeLog +++ b/cpukit/score/ChangeLog @@ -1,3 +1,11 @@ +2005-08-17 Andrew Sinclair <Andrew.Sinclair@elprotech.com> + + PR 807/rtems + * rtems/src/timerfireafter.c, rtems/src/timerserverfireafter.c, + score/src/watchdoginsert.c: Tighten critical section checks on an ISR + using the same timer being inserted by a lower priority ISR or + interupt task. + 2005-05-13 Jennifer Averett <jennifer.averett@oarcorp.com> PR 786/rtems diff --git a/cpukit/score/src/watchdoginsert.c b/cpukit/score/src/watchdoginsert.c index 4e921e28c8..5dfea56a46 100644 --- a/cpukit/score/src/watchdoginsert.c +++ b/cpukit/score/src/watchdoginsert.c @@ -36,10 +36,20 @@ void _Watchdog_Insert( insert_isr_nest_level = _ISR_Nest_level; - the_watchdog->state = WATCHDOG_BEING_INSERTED; _ISR_Disable( level ); + /* + * Check to see if the watchdog has just been inserted by a + * higher priority interrupt. If so, abandon this insert. + */ + + if ( the_watchdog->state != WATCHDOG_INACTIVE ) { + _ISR_Enable( level ); + return; + } + + the_watchdog->state = WATCHDOG_BEING_INSERTED; _Watchdog_Sync_count++; restart: |