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.
This commit is contained in:
Joel Sherrill
2005-08-17 22:49:56 +00:00
parent 27178a8173
commit 55e012993c
4 changed files with 66 additions and 6 deletions
+8
View File
@@ -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-08-17 Nickolay Semyonov <snob@oktetlabs.ru>
PR 744/filesystem
+24 -2
View File
@@ -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;
+23 -3
View File
@@ -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();
+11 -1
View File
@@ -40,10 +40,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: