summaryrefslogtreecommitdiffstats
path: root/cpukit/rtems
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cpukit/rtems/ChangeLog11
-rw-r--r--cpukit/rtems/include/rtems/rtems/timer.h51
-rw-r--r--cpukit/rtems/src/timerreset.c3
-rw-r--r--cpukit/rtems/src/timerserver.c73
-rw-r--r--cpukit/rtems/src/timerserverfireafter.c6
-rw-r--r--cpukit/rtems/src/timerserverfirewhen.c6
6 files changed, 73 insertions, 77 deletions
diff --git a/cpukit/rtems/ChangeLog b/cpukit/rtems/ChangeLog
index 2267089f56..2a5f9b705a 100644
--- a/cpukit/rtems/ChangeLog
+++ b/cpukit/rtems/ChangeLog
@@ -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>
* Makefile.am: Remove AUTOMAKE_OPTIONS.
diff --git a/cpukit/rtems/include/rtems/rtems/timer.h b/cpukit/rtems/include/rtems/rtems/timer.h
index a1f2434c34..6f5ea3a512 100644
--- a/cpukit/rtems/include/rtems/rtems/timer.h
+++ b/cpukit/rtems/include/rtems/rtems/timer.h
@@ -135,24 +135,6 @@ Thread _Timer_Server_body(
);
/*
- * _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
*
* DESCRIPTION:
@@ -339,6 +321,39 @@ rtems_status_code rtems_timer_get_information(
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__
#include <rtems/rtems/timer.inl>
#endif
diff --git a/cpukit/rtems/src/timerreset.c b/cpukit/rtems/src/timerreset.c
index 33a45e1fc3..796fb5ecfb 100644
--- a/cpukit/rtems/src/timerreset.c
+++ b/cpukit/rtems/src/timerreset.c
@@ -57,8 +57,11 @@ rtems_status_code rtems_timer_reset(
_Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker );
break;
case TIMER_INTERVAL_ON_TASK:
+ _Timer_Server_stop_ticks_timer();
_Watchdog_Remove( &the_timer->Ticker );
+ _Timer_Server_process_ticks_chain();
_Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
+ _Timer_Server_reset_ticks_timer();
break;
case TIMER_TIME_OF_DAY:
case TIMER_TIME_OF_DAY_ON_TASK:
diff --git a/cpukit/rtems/src/timerserver.c b/cpukit/rtems/src/timerserver.c
index dace8f8c45..902f94aaf1 100644
--- a/cpukit/rtems/src/timerserver.c
+++ b/cpukit/rtems/src/timerserver.c
@@ -49,19 +49,10 @@ Watchdog_Interval _Timer_Server_ticks_last_time;
/*
* The timer used to control when the Timer Server wakes up to service
* "when" timers.
- *
- * NOTE: This should NOT be used outside this file.
*/
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
*
* _Timer_Server_body
@@ -97,10 +88,18 @@ Thread _Timer_Server_body(
*/
_Thread_Set_state( _Timer_Server, STATES_DELAYING );
- _Timer_Server_reset( TIMER_SERVER_RESET_TICKS );
- _Timer_Server_reset( TIMER_SERVER_RESET_SECONDS );
+ _Timer_Server_reset_ticks_timer();
+ _Timer_Server_reset_seconds_timer();
_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
@@ -110,8 +109,8 @@ Thread _Timer_Server_body(
*/
_Thread_Disable_dispatch();
- _Timer_Process_ticks_chain();
- _Timer_Process_seconds_chain();
+ _Timer_Server_process_ticks_chain();
+ _Timer_Server_process_seconds_chain();
}
}
@@ -245,47 +244,7 @@ rtems_status_code rtems_timer_initiate_server(
/*PAGE
*
- * _Timer_Server_reset
- *
- * 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
+ * _Timer_Server_process_ticks_chain
*
* This routine is responsible for adjusting the list of task-based
* interval timers to reflect the passage of time.
@@ -295,7 +254,7 @@ void _Timer_Server_reset(
* Output parameters: NONE
*/
-void _Timer_Process_ticks_chain(void)
+void _Timer_Server_process_ticks_chain(void)
{
Watchdog_Interval snapshot;
Watchdog_Interval ticks;
@@ -312,7 +271,7 @@ void _Timer_Process_ticks_chain(void)
/*PAGE
*
- * _Timer_Server_Process_seconds_chain
+ * _Timer_Server_process_seconds_chain
*
* This routine is responsible for adjusting the list of task-based
* time of day timers to reflect the passage of time.
@@ -322,7 +281,7 @@ void _Timer_Process_ticks_chain(void)
* Output parameters: NONE
*/
-void _Timer_Process_seconds_chain(void)
+void _Timer_Server_process_seconds_chain(void)
{
Watchdog_Interval snapshot;
Watchdog_Interval ticks;
diff --git a/cpukit/rtems/src/timerserverfireafter.c b/cpukit/rtems/src/timerserverfireafter.c
index 32b42b77ce..8c53449f1d 100644
--- a/cpukit/rtems/src/timerserverfireafter.c
+++ b/cpukit/rtems/src/timerserverfireafter.c
@@ -69,8 +69,12 @@ rtems_status_code rtems_timer_server_fire_after(
the_timer->the_class = TIMER_INTERVAL_ON_TASK;
_Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
the_timer->Ticker.initial = ticks;
+
+ _Timer_Server_stop_ticks_timer();
+ _Timer_Server_process_ticks_chain();
_Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker );
- _Timer_Server_reset( TIMER_SERVER_RESET_TICKS );
+ _Timer_Server_reset_ticks_timer();
+
_Thread_Enable_dispatch();
return RTEMS_SUCCESSFUL;
}
diff --git a/cpukit/rtems/src/timerserverfirewhen.c b/cpukit/rtems/src/timerserverfirewhen.c
index 6309315a75..4385d06cf8 100644
--- a/cpukit/rtems/src/timerserverfirewhen.c
+++ b/cpukit/rtems/src/timerserverfirewhen.c
@@ -77,8 +77,12 @@ rtems_status_code rtems_timer_server_fire_when(
the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK;
_Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data );
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 );
- _Timer_Server_reset( TIMER_SERVER_RESET_SECONDS );
+ _Timer_Server_reset_seconds_timer();
+
_Thread_Enable_dispatch();
return RTEMS_SUCCESSFUL;
}