Index: c/src/exec/rtems/ChangeLog
===================================================================
--- c/src/exec/rtems/ChangeLog	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ c/src/exec/rtems/ChangeLog	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -1,2 +1,13 @@
+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>
 
Index: c/src/exec/rtems/include/rtems/rtems/timer.h
===================================================================
--- c/src/exec/rtems/include/rtems/rtems/timer.h	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ c/src/exec/rtems/include/rtems/rtems/timer.h	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -136,22 +136,4 @@
 
 /*
- *  _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
  *
@@ -340,4 +322,37 @@
 );
 
+/*
+ *  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>
Index: c/src/exec/rtems/src/timerreset.c
===================================================================
--- c/src/exec/rtems/src/timerreset.c	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ c/src/exec/rtems/src/timerreset.c	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -58,6 +58,9 @@
           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:
Index: c/src/exec/rtems/src/timerserver.c
===================================================================
--- c/src/exec/rtems/src/timerserver.c	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ c/src/exec/rtems/src/timerserver.c	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -50,16 +50,7 @@
  *  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
@@ -98,8 +89,16 @@
 
       _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();
 
     /*
@@ -111,6 +110,6 @@
 
     _Thread_Disable_dispatch();
-      _Timer_Process_ticks_chain();
-      _Timer_Process_seconds_chain();
+      _Timer_Server_process_ticks_chain();
+      _Timer_Server_process_seconds_chain();
   }
 }
@@ -246,45 +245,5 @@
 /*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 
@@ -296,5 +255,5 @@
  */
 
-void _Timer_Process_ticks_chain(void)
+void _Timer_Server_process_ticks_chain(void)
 {
   Watchdog_Interval snapshot;
@@ -313,5 +272,5 @@
 /*PAGE
  *
- *  _Timer_Server_Process_seconds_chain
+ *  _Timer_Server_process_seconds_chain
  *
  *  This routine is responsible for adjusting the list of task-based 
@@ -323,5 +282,5 @@
  */
 
-void _Timer_Process_seconds_chain(void)
+void _Timer_Server_process_seconds_chain(void)
 {
   Watchdog_Interval snapshot;
Index: c/src/exec/rtems/src/timerserverfireafter.c
===================================================================
--- c/src/exec/rtems/src/timerserverfireafter.c	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ c/src/exec/rtems/src/timerserverfireafter.c	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -70,6 +70,10 @@
       _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;
Index: c/src/exec/rtems/src/timerserverfirewhen.c
===================================================================
--- c/src/exec/rtems/src/timerserverfirewhen.c	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ c/src/exec/rtems/src/timerserverfirewhen.c	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -78,6 +78,10 @@
       _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;
Index: cpukit/rtems/ChangeLog
===================================================================
--- cpukit/rtems/ChangeLog	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ cpukit/rtems/ChangeLog	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -1,2 +1,13 @@
+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>
 
Index: cpukit/rtems/include/rtems/rtems/timer.h
===================================================================
--- cpukit/rtems/include/rtems/rtems/timer.h	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ cpukit/rtems/include/rtems/rtems/timer.h	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -136,22 +136,4 @@
 
 /*
- *  _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
  *
@@ -340,4 +322,37 @@
 );
 
+/*
+ *  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>
Index: cpukit/rtems/src/timerreset.c
===================================================================
--- cpukit/rtems/src/timerreset.c	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ cpukit/rtems/src/timerreset.c	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -58,6 +58,9 @@
           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:
Index: cpukit/rtems/src/timerserver.c
===================================================================
--- cpukit/rtems/src/timerserver.c	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ cpukit/rtems/src/timerserver.c	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -50,16 +50,7 @@
  *  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
@@ -98,8 +89,16 @@
 
       _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();
 
     /*
@@ -111,6 +110,6 @@
 
     _Thread_Disable_dispatch();
-      _Timer_Process_ticks_chain();
-      _Timer_Process_seconds_chain();
+      _Timer_Server_process_ticks_chain();
+      _Timer_Server_process_seconds_chain();
   }
 }
@@ -246,45 +245,5 @@
 /*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 
@@ -296,5 +255,5 @@
  */
 
-void _Timer_Process_ticks_chain(void)
+void _Timer_Server_process_ticks_chain(void)
 {
   Watchdog_Interval snapshot;
@@ -313,5 +272,5 @@
 /*PAGE
  *
- *  _Timer_Server_Process_seconds_chain
+ *  _Timer_Server_process_seconds_chain
  *
  *  This routine is responsible for adjusting the list of task-based 
@@ -323,5 +282,5 @@
  */
 
-void _Timer_Process_seconds_chain(void)
+void _Timer_Server_process_seconds_chain(void)
 {
   Watchdog_Interval snapshot;
Index: cpukit/rtems/src/timerserverfireafter.c
===================================================================
--- cpukit/rtems/src/timerserverfireafter.c	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ cpukit/rtems/src/timerserverfireafter.c	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -70,6 +70,10 @@
       _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;
Index: cpukit/rtems/src/timerserverfirewhen.c
===================================================================
--- cpukit/rtems/src/timerserverfirewhen.c	(revision 5729f62e12673f322451fd4dcd6e790ec1e2ccef)
+++ cpukit/rtems/src/timerserverfirewhen.c	(revision 894d01c2d401bbd472ddec9f025ca14b25ec4e5d)
@@ -78,6 +78,10 @@
       _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;
