diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2005-08-17 22:49:56 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2005-08-17 22:49:56 +0000 |
commit | 55e012993ca8e7ee9bf38d53158db7bc56b815b4 (patch) | |
tree | 99927b48729584a5dc14bbb9aa83c632f8ab7b72 /cpukit/rtems/src | |
parent | New file. (diff) | |
download | rtems-55e012993ca8e7ee9bf38d53158db7bc56b815b4.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.
Diffstat (limited to 'cpukit/rtems/src')
-rw-r--r-- | cpukit/rtems/src/timerfireafter.c | 26 | ||||
-rw-r--r-- | cpukit/rtems/src/timerserverfireafter.c | 26 |
2 files changed, 47 insertions, 5 deletions
diff --git a/cpukit/rtems/src/timerfireafter.c b/cpukit/rtems/src/timerfireafter.c index cead1426a4..98b5d36e91 100644 --- a/cpukit/rtems/src/timerfireafter.c +++ b/cpukit/rtems/src/timerfireafter.c @@ -51,6 +51,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; @@ -68,8 +69,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 9174459346..849de800a2 100644 --- a/cpukit/rtems/src/timerserverfireafter.c +++ b/cpukit/rtems/src/timerserverfireafter.c @@ -52,6 +52,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 ) @@ -73,9 +74,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(); |