2001-03-29 Joel Sherrill <joel@OARcorp.com>

* Per PR147 addressed problems when reseting and inserting a timer
	into a timer chain that did not honor time passage since the last
	time the timer server was scheduled and the new insertion.
	* include/rtems/rtems/timer.h, src/timerreset.c, src/timerserver.c,
	src/timerserverfireafter.c, src/timerserverfirewhen.c: Broke up
	the "reset server" routine into a set of very specific routines
	that allowed the server to be unscheduled, timer chains to be
	"synchronized" with the current time before inserting a new timer.
This commit is contained in:
Joel Sherrill
2002-03-29 15:32:18 +00:00
parent 5729f62e12
commit 894d01c2d4
12 changed files with 146 additions and 154 deletions

View File

@@ -1,3 +1,14 @@
2001-03-29 Joel Sherrill <joel@OARcorp.com>
* Per PR147 addressed problems when reseting and inserting a timer
into a timer chain that did not honor time passage since the last
time the timer server was scheduled and the new insertion.
* include/rtems/rtems/timer.h, src/timerreset.c, src/timerserver.c,
src/timerserverfireafter.c, src/timerserverfirewhen.c: Broke up
the "reset server" routine into a set of very specific routines
that allowed the server to be unscheduled, timer chains to be
"synchronized" with the current time before inserting a new timer.
2002-03-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de> 2002-03-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Remove AUTOMAKE_OPTIONS. * Makefile.am: Remove AUTOMAKE_OPTIONS.

View File

@@ -134,24 +134,6 @@ Thread _Timer_Server_body(
unsigned32 ignored unsigned32 ignored
); );
/*
* _Timer_Server_reset
*
* DESCRIPTION:
*
* This routine resets the timers which determine when the Timer Server
* will wake up next to service task-based timers.
*/
typedef enum {
TIMER_SERVER_RESET_TICKS,
TIMER_SERVER_RESET_SECONDS
} Timer_Server_reset_mode;
void _Timer_Server_reset(
Timer_Server_reset_mode reset_mode
);
/* /*
* rtems_timer_create * rtems_timer_create
* *
@@ -339,6 +321,39 @@ rtems_status_code rtems_timer_get_information(
rtems_timer_information *the_info rtems_timer_information *the_info
); );
/*
* Macros and routines that expose the mechanisms required to service
* the Timer Server timer. These stop the timer, synchronize it with
* the current time, and restart it.
*/
extern Watchdog_Control _Timer_Seconds_timer;
#define _Timer_Server_stop_ticks_timer() \
_Watchdog_Remove( &_Timer_Server->Timer )
#define _Timer_Server_stop_seconds_timer() \
_Watchdog_Remove( &_Timer_Seconds_timer );
void _Timer_Server_process_ticks_chain(void);
void _Timer_Server_process_seconds_chain(void);
#define _Timer_Server_reset_ticks_timer() \
do { \
if ( !_Chain_Is_empty( &_Timer_Ticks_chain ) ) { \
_Watchdog_Insert_ticks( &_Timer_Server->Timer, \
((Watchdog_Control *)_Timer_Ticks_chain.first)->delta_interval ); \
} \
} while (0)
#define _Timer_Server_reset_seconds_timer() \
do { \
if ( !_Chain_Is_empty( &_Timer_Seconds_chain ) ) { \
_Watchdog_Insert_seconds( &_Timer_Seconds_timer, \
((Watchdog_Control *)_Timer_Seconds_chain.first)->delta_interval ); \
} \
} while (0)
#ifndef __RTEMS_APPLICATION__ #ifndef __RTEMS_APPLICATION__
#include <rtems/rtems/timer.inl> #include <rtems/rtems/timer.inl>
#endif #endif

View File

@@ -57,8 +57,11 @@ rtems_status_code rtems_timer_reset(
_Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker ); _Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker );
break; break;
case TIMER_INTERVAL_ON_TASK: case TIMER_INTERVAL_ON_TASK:
_Timer_Server_stop_ticks_timer();
_Watchdog_Remove( &the_timer->Ticker ); _Watchdog_Remove( &the_timer->Ticker );
_Timer_Server_process_ticks_chain();
_Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker ); _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
_Timer_Server_reset_ticks_timer();
break; break;
case TIMER_TIME_OF_DAY: case TIMER_TIME_OF_DAY:
case TIMER_TIME_OF_DAY_ON_TASK: case TIMER_TIME_OF_DAY_ON_TASK:

View File

@@ -49,19 +49,10 @@ Watchdog_Interval _Timer_Server_ticks_last_time;
/* /*
* The timer used to control when the Timer Server wakes up to service * The timer used to control when the Timer Server wakes up to service
* "when" timers. * "when" timers.
*
* NOTE: This should NOT be used outside this file.
*/ */
Watchdog_Control _Timer_Seconds_timer; Watchdog_Control _Timer_Seconds_timer;
/*
* prototypes for support routines to process the chains
*/
void _Timer_Process_ticks_chain(void);
void _Timer_Process_seconds_chain(void);
/*PAGE /*PAGE
* *
* _Timer_Server_body * _Timer_Server_body
@@ -97,10 +88,18 @@ Thread _Timer_Server_body(
*/ */
_Thread_Set_state( _Timer_Server, STATES_DELAYING ); _Thread_Set_state( _Timer_Server, STATES_DELAYING );
_Timer_Server_reset( TIMER_SERVER_RESET_TICKS ); _Timer_Server_reset_ticks_timer();
_Timer_Server_reset( TIMER_SERVER_RESET_SECONDS ); _Timer_Server_reset_seconds_timer();
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
/*
* At this point, at least one of the timers this task relies
* upon has fired. Stop them both while we process any outstanding
* timers. Before we block, we will restart them.
*/
_Timer_Server_stop_ticks_timer();
_Timer_Server_stop_seconds_timer();
/* /*
* Disable dispatching while processing the timers since we want * Disable dispatching while processing the timers since we want
@@ -110,8 +109,8 @@ Thread _Timer_Server_body(
*/ */
_Thread_Disable_dispatch(); _Thread_Disable_dispatch();
_Timer_Process_ticks_chain(); _Timer_Server_process_ticks_chain();
_Timer_Process_seconds_chain(); _Timer_Server_process_seconds_chain();
} }
} }
@@ -245,47 +244,7 @@ rtems_status_code rtems_timer_initiate_server(
/*PAGE /*PAGE
* *
* _Timer_Server_reset * _Timer_Server_process_ticks_chain
*
* This routine resets the timers which determine when the Timer Server
* will wake up next to service task-based timers.
*
* Input parameters:
* do_ticks - TRUE indicates to process the ticks list
* FALSE indicates to process the seconds list
*
* Output parameters: NONE
*/
void _Timer_Server_reset(
Timer_Server_reset_mode reset_mode
)
{
Watchdog_Interval units;
switch ( reset_mode ) {
case TIMER_SERVER_RESET_TICKS:
_Watchdog_Remove( &_Timer_Server->Timer );
_Timer_Process_ticks_chain();
if ( !_Chain_Is_empty( &_Timer_Ticks_chain ) ) {
units = ((Watchdog_Control *)_Timer_Ticks_chain.first)->delta_interval;
_Watchdog_Insert_ticks( &_Timer_Server->Timer, units );
}
break;
case TIMER_SERVER_RESET_SECONDS:
_Watchdog_Remove( &_Timer_Seconds_timer );
_Timer_Process_seconds_chain();
if ( !_Chain_Is_empty( &_Timer_Seconds_chain ) ) {
units = ((Watchdog_Control *)_Timer_Seconds_chain.first)->delta_interval;
_Watchdog_Insert_seconds( &_Timer_Seconds_timer, units );
}
break;
}
}
/*PAGE
*
* _Timer_Server_Process_ticks_chain
* *
* This routine is responsible for adjusting the list of task-based * This routine is responsible for adjusting the list of task-based
* interval timers to reflect the passage of time. * interval timers to reflect the passage of time.
@@ -295,7 +254,7 @@ void _Timer_Server_reset(
* Output parameters: NONE * Output parameters: NONE
*/ */
void _Timer_Process_ticks_chain(void) void _Timer_Server_process_ticks_chain(void)
{ {
Watchdog_Interval snapshot; Watchdog_Interval snapshot;
Watchdog_Interval ticks; Watchdog_Interval ticks;
@@ -312,7 +271,7 @@ void _Timer_Process_ticks_chain(void)
/*PAGE /*PAGE
* *
* _Timer_Server_Process_seconds_chain * _Timer_Server_process_seconds_chain
* *
* This routine is responsible for adjusting the list of task-based * This routine is responsible for adjusting the list of task-based
* time of day timers to reflect the passage of time. * time of day timers to reflect the passage of time.
@@ -322,7 +281,7 @@ void _Timer_Process_ticks_chain(void)
* Output parameters: NONE * Output parameters: NONE
*/ */
void _Timer_Process_seconds_chain(void) void _Timer_Server_process_seconds_chain(void)
{ {
Watchdog_Interval snapshot; Watchdog_Interval snapshot;
Watchdog_Interval ticks; Watchdog_Interval ticks;

View File

@@ -69,8 +69,12 @@ rtems_status_code rtems_timer_server_fire_after(
the_timer->the_class = TIMER_INTERVAL_ON_TASK; the_timer->the_class = TIMER_INTERVAL_ON_TASK;
_Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
the_timer->Ticker.initial = ticks; the_timer->Ticker.initial = ticks;
_Timer_Server_stop_ticks_timer();
_Timer_Server_process_ticks_chain();
_Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker ); _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
_Timer_Server_reset( TIMER_SERVER_RESET_TICKS ); _Timer_Server_reset_ticks_timer();
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }

View File

@@ -77,8 +77,12 @@ rtems_status_code rtems_timer_server_fire_when(
the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK; the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK;
_Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch; the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch;
_Timer_Server_stop_seconds_timer();
_Timer_Server_process_seconds_chain();
_Watchdog_Insert( &_Timer_Seconds_chain, &the_timer->Ticker ); _Watchdog_Insert( &_Timer_Seconds_chain, &the_timer->Ticker );
_Timer_Server_reset( TIMER_SERVER_RESET_SECONDS ); _Timer_Server_reset_seconds_timer();
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }

View File

@@ -1,3 +1,14 @@
2001-03-29 Joel Sherrill <joel@OARcorp.com>
* Per PR147 addressed problems when reseting and inserting a timer
into a timer chain that did not honor time passage since the last
time the timer server was scheduled and the new insertion.
* include/rtems/rtems/timer.h, src/timerreset.c, src/timerserver.c,
src/timerserverfireafter.c, src/timerserverfirewhen.c: Broke up
the "reset server" routine into a set of very specific routines
that allowed the server to be unscheduled, timer chains to be
"synchronized" with the current time before inserting a new timer.
2002-03-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de> 2002-03-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Remove AUTOMAKE_OPTIONS. * Makefile.am: Remove AUTOMAKE_OPTIONS.

View File

@@ -134,24 +134,6 @@ Thread _Timer_Server_body(
unsigned32 ignored unsigned32 ignored
); );
/*
* _Timer_Server_reset
*
* DESCRIPTION:
*
* This routine resets the timers which determine when the Timer Server
* will wake up next to service task-based timers.
*/
typedef enum {
TIMER_SERVER_RESET_TICKS,
TIMER_SERVER_RESET_SECONDS
} Timer_Server_reset_mode;
void _Timer_Server_reset(
Timer_Server_reset_mode reset_mode
);
/* /*
* rtems_timer_create * rtems_timer_create
* *
@@ -339,6 +321,39 @@ rtems_status_code rtems_timer_get_information(
rtems_timer_information *the_info rtems_timer_information *the_info
); );
/*
* Macros and routines that expose the mechanisms required to service
* the Timer Server timer. These stop the timer, synchronize it with
* the current time, and restart it.
*/
extern Watchdog_Control _Timer_Seconds_timer;
#define _Timer_Server_stop_ticks_timer() \
_Watchdog_Remove( &_Timer_Server->Timer )
#define _Timer_Server_stop_seconds_timer() \
_Watchdog_Remove( &_Timer_Seconds_timer );
void _Timer_Server_process_ticks_chain(void);
void _Timer_Server_process_seconds_chain(void);
#define _Timer_Server_reset_ticks_timer() \
do { \
if ( !_Chain_Is_empty( &_Timer_Ticks_chain ) ) { \
_Watchdog_Insert_ticks( &_Timer_Server->Timer, \
((Watchdog_Control *)_Timer_Ticks_chain.first)->delta_interval ); \
} \
} while (0)
#define _Timer_Server_reset_seconds_timer() \
do { \
if ( !_Chain_Is_empty( &_Timer_Seconds_chain ) ) { \
_Watchdog_Insert_seconds( &_Timer_Seconds_timer, \
((Watchdog_Control *)_Timer_Seconds_chain.first)->delta_interval ); \
} \
} while (0)
#ifndef __RTEMS_APPLICATION__ #ifndef __RTEMS_APPLICATION__
#include <rtems/rtems/timer.inl> #include <rtems/rtems/timer.inl>
#endif #endif

View File

@@ -57,8 +57,11 @@ rtems_status_code rtems_timer_reset(
_Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker ); _Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker );
break; break;
case TIMER_INTERVAL_ON_TASK: case TIMER_INTERVAL_ON_TASK:
_Timer_Server_stop_ticks_timer();
_Watchdog_Remove( &the_timer->Ticker ); _Watchdog_Remove( &the_timer->Ticker );
_Timer_Server_process_ticks_chain();
_Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker ); _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
_Timer_Server_reset_ticks_timer();
break; break;
case TIMER_TIME_OF_DAY: case TIMER_TIME_OF_DAY:
case TIMER_TIME_OF_DAY_ON_TASK: case TIMER_TIME_OF_DAY_ON_TASK:

View File

@@ -49,19 +49,10 @@ Watchdog_Interval _Timer_Server_ticks_last_time;
/* /*
* The timer used to control when the Timer Server wakes up to service * The timer used to control when the Timer Server wakes up to service
* "when" timers. * "when" timers.
*
* NOTE: This should NOT be used outside this file.
*/ */
Watchdog_Control _Timer_Seconds_timer; Watchdog_Control _Timer_Seconds_timer;
/*
* prototypes for support routines to process the chains
*/
void _Timer_Process_ticks_chain(void);
void _Timer_Process_seconds_chain(void);
/*PAGE /*PAGE
* *
* _Timer_Server_body * _Timer_Server_body
@@ -97,10 +88,18 @@ Thread _Timer_Server_body(
*/ */
_Thread_Set_state( _Timer_Server, STATES_DELAYING ); _Thread_Set_state( _Timer_Server, STATES_DELAYING );
_Timer_Server_reset( TIMER_SERVER_RESET_TICKS ); _Timer_Server_reset_ticks_timer();
_Timer_Server_reset( TIMER_SERVER_RESET_SECONDS ); _Timer_Server_reset_seconds_timer();
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
/*
* At this point, at least one of the timers this task relies
* upon has fired. Stop them both while we process any outstanding
* timers. Before we block, we will restart them.
*/
_Timer_Server_stop_ticks_timer();
_Timer_Server_stop_seconds_timer();
/* /*
* Disable dispatching while processing the timers since we want * Disable dispatching while processing the timers since we want
@@ -110,8 +109,8 @@ Thread _Timer_Server_body(
*/ */
_Thread_Disable_dispatch(); _Thread_Disable_dispatch();
_Timer_Process_ticks_chain(); _Timer_Server_process_ticks_chain();
_Timer_Process_seconds_chain(); _Timer_Server_process_seconds_chain();
} }
} }
@@ -245,47 +244,7 @@ rtems_status_code rtems_timer_initiate_server(
/*PAGE /*PAGE
* *
* _Timer_Server_reset * _Timer_Server_process_ticks_chain
*
* This routine resets the timers which determine when the Timer Server
* will wake up next to service task-based timers.
*
* Input parameters:
* do_ticks - TRUE indicates to process the ticks list
* FALSE indicates to process the seconds list
*
* Output parameters: NONE
*/
void _Timer_Server_reset(
Timer_Server_reset_mode reset_mode
)
{
Watchdog_Interval units;
switch ( reset_mode ) {
case TIMER_SERVER_RESET_TICKS:
_Watchdog_Remove( &_Timer_Server->Timer );
_Timer_Process_ticks_chain();
if ( !_Chain_Is_empty( &_Timer_Ticks_chain ) ) {
units = ((Watchdog_Control *)_Timer_Ticks_chain.first)->delta_interval;
_Watchdog_Insert_ticks( &_Timer_Server->Timer, units );
}
break;
case TIMER_SERVER_RESET_SECONDS:
_Watchdog_Remove( &_Timer_Seconds_timer );
_Timer_Process_seconds_chain();
if ( !_Chain_Is_empty( &_Timer_Seconds_chain ) ) {
units = ((Watchdog_Control *)_Timer_Seconds_chain.first)->delta_interval;
_Watchdog_Insert_seconds( &_Timer_Seconds_timer, units );
}
break;
}
}
/*PAGE
*
* _Timer_Server_Process_ticks_chain
* *
* This routine is responsible for adjusting the list of task-based * This routine is responsible for adjusting the list of task-based
* interval timers to reflect the passage of time. * interval timers to reflect the passage of time.
@@ -295,7 +254,7 @@ void _Timer_Server_reset(
* Output parameters: NONE * Output parameters: NONE
*/ */
void _Timer_Process_ticks_chain(void) void _Timer_Server_process_ticks_chain(void)
{ {
Watchdog_Interval snapshot; Watchdog_Interval snapshot;
Watchdog_Interval ticks; Watchdog_Interval ticks;
@@ -312,7 +271,7 @@ void _Timer_Process_ticks_chain(void)
/*PAGE /*PAGE
* *
* _Timer_Server_Process_seconds_chain * _Timer_Server_process_seconds_chain
* *
* This routine is responsible for adjusting the list of task-based * This routine is responsible for adjusting the list of task-based
* time of day timers to reflect the passage of time. * time of day timers to reflect the passage of time.
@@ -322,7 +281,7 @@ void _Timer_Process_ticks_chain(void)
* Output parameters: NONE * Output parameters: NONE
*/ */
void _Timer_Process_seconds_chain(void) void _Timer_Server_process_seconds_chain(void)
{ {
Watchdog_Interval snapshot; Watchdog_Interval snapshot;
Watchdog_Interval ticks; Watchdog_Interval ticks;

View File

@@ -69,8 +69,12 @@ rtems_status_code rtems_timer_server_fire_after(
the_timer->the_class = TIMER_INTERVAL_ON_TASK; the_timer->the_class = TIMER_INTERVAL_ON_TASK;
_Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
the_timer->Ticker.initial = ticks; the_timer->Ticker.initial = ticks;
_Timer_Server_stop_ticks_timer();
_Timer_Server_process_ticks_chain();
_Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker ); _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
_Timer_Server_reset( TIMER_SERVER_RESET_TICKS ); _Timer_Server_reset_ticks_timer();
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }

View File

@@ -77,8 +77,12 @@ rtems_status_code rtems_timer_server_fire_when(
the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK; the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK;
_Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch; the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch;
_Timer_Server_stop_seconds_timer();
_Timer_Server_process_seconds_chain();
_Watchdog_Insert( &_Timer_Seconds_chain, &the_timer->Ticker ); _Watchdog_Insert( &_Timer_Seconds_chain, &the_timer->Ticker );
_Timer_Server_reset( TIMER_SERVER_RESET_SECONDS ); _Timer_Server_reset_seconds_timer();
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
return RTEMS_SUCCESSFUL; return RTEMS_SUCCESSFUL;
} }