Ticket #147: pr147.diff
File pr147.diff, 14.4 KB (added by Joel Sherrill, on 12/03/06 at 13:31:13) |
---|
-
new file c/src/exec/rtems/changes
- + 1 2001-03-29 Joel Sherrill <joel@OARcorp.com> 2 3 * Per PR147 addressed problems when reseting and inserting a timer 4 into a timer chain that did not honor time passage since the last 5 time the timer server was scheduled and the new insertion. 6 * include/rtems/rtems/timer.h, src/timerreset.c, src/timerserver.c, 7 src/timerserverfireafter.c, src/timerserverfirewhen.c: Broke up 8 the "reset server" routine into a set of very specific routines 9 that allowed the server to be unscheduled, timer chains to be 10 "synchronized" with the current time before inserting a new timer. 11 -
new file c/src/tests/sptests/changes
- + 1 2001-03-29 Joel Sherrill <joel@OARcorp.com> 2 3 * Per PR147 addressed problems when reseting and inserting a timer 4 into a timer chain that did not honor time passage since the last 5 time the timer server was scheduled and the new insertion. 6 * sp31/sp31.scn, sp31/task1.c: Added test code to detect this case. 7 -
c/src/exec/rtems/include/rtems/rtems/timer.h
RCS file: /usr1/CVS/rtems/c/src/exec/rtems/include/rtems/rtems/timer.h,v retrieving revision 1.11.4.3 diff -u -r1.11.4.3 timer.h
135 135 ); 136 136 137 137 /* 138 * _Timer_Server_reset139 *140 * DESCRIPTION:141 *142 * This routine resets the timers which determine when the Timer Server143 * will wake up next to service task-based timers.144 */145 146 typedef enum {147 TIMER_SERVER_RESET_TICKS,148 TIMER_SERVER_RESET_SECONDS149 } Timer_Server_reset_mode;150 151 void _Timer_Server_reset(152 Timer_Server_reset_mode reset_mode153 );154 155 /*156 138 * rtems_timer_create 157 139 * 158 140 * DESCRIPTION: … … 338 320 Objects_Id id, 339 321 rtems_timer_information *the_info 340 322 ); 323 324 /* 325 * Macros and routines that expose the mechanisms required to service 326 * the Timer Server timer. These stop the timer, synchronize it with 327 * the current time, and restart it. 328 */ 329 330 extern Watchdog_Control _Timer_Seconds_timer; 331 332 #define _Timer_Server_stop_ticks_timer() \ 333 _Watchdog_Remove( &_Timer_Server->Timer ) 334 335 #define _Timer_Server_stop_seconds_timer() \ 336 _Watchdog_Remove( &_Timer_Seconds_timer ); 337 338 void _Timer_Server_process_ticks_chain(void); 339 void _Timer_Server_process_seconds_chain(void); 340 341 #define _Timer_Server_reset_ticks_timer() \ 342 do { \ 343 if ( !_Chain_Is_empty( &_Timer_Ticks_chain ) ) { \ 344 _Watchdog_Insert_ticks( &_Timer_Server->Timer, \ 345 ((Watchdog_Control *)_Timer_Ticks_chain.first)->delta_interval ); \ 346 } \ 347 } while (0) 348 349 #define _Timer_Server_reset_seconds_timer() \ 350 do { \ 351 if ( !_Chain_Is_empty( &_Timer_Seconds_chain ) ) { \ 352 _Watchdog_Insert_seconds( &_Timer_Seconds_timer, \ 353 ((Watchdog_Control *)_Timer_Seconds_chain.first)->delta_interval ); \ 354 } \ 355 } while (0) 341 356 342 357 #ifndef __RTEMS_APPLICATION__ 343 358 #include <rtems/rtems/timer.inl> -
c/src/exec/rtems/src/timerreset.c
RCS file: /usr1/CVS/rtems/c/src/exec/rtems/src/timerreset.c,v retrieving revision 1.2.4.1 diff -u -r1.2.4.1 timerreset.c
57 57 _Watchdog_Insert( &_Watchdog_Ticks_chain, &the_timer->Ticker ); 58 58 break; 59 59 case TIMER_INTERVAL_ON_TASK: 60 _Timer_Server_stop_ticks_timer(); 60 61 _Watchdog_Remove( &the_timer->Ticker ); 62 _Timer_Server_process_ticks_chain(); 61 63 _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker ); 64 _Timer_Server_reset_ticks_timer(); 62 65 break; 63 66 case TIMER_TIME_OF_DAY: 64 67 case TIMER_TIME_OF_DAY_ON_TASK: -
c/src/exec/rtems/src/timerserver.c
RCS file: /usr1/CVS/rtems/c/src/exec/rtems/src/timerserver.c,v retrieving revision 1.1.2.3 diff -u -r1.1.2.3 timerserver.c
49 49 /* 50 50 * The timer used to control when the Timer Server wakes up to service 51 51 * "when" timers. 52 *53 * NOTE: This should NOT be used outside this file.54 52 */ 55 53 56 54 Watchdog_Control _Timer_Seconds_timer; 57 55 58 /*59 * prototypes for support routines to process the chains60 */61 62 void _Timer_Process_ticks_chain(void);63 void _Timer_Process_seconds_chain(void);64 65 56 /*PAGE 66 57 * 67 58 * _Timer_Server_body … … 97 88 */ 98 89 99 90 _Thread_Set_state( _Timer_Server, STATES_DELAYING ); 100 _Timer_Server_reset ( TIMER_SERVER_RESET_TICKS);101 _Timer_Server_reset ( TIMER_SERVER_RESET_SECONDS);91 _Timer_Server_reset_ticks_timer(); 92 _Timer_Server_reset_seconds_timer(); 102 93 _Thread_Enable_dispatch(); 103 94 95 /* 96 * At this point, at least one of the timers this task relies 97 * upon has fired. Stop them both while we process any outstanding 98 * timers. Before we block, we will restart them. 99 */ 100 101 _Timer_Server_stop_ticks_timer(); 102 _Timer_Server_stop_seconds_timer(); 104 103 105 104 /* 106 105 * Disable dispatching while processing the timers since we want … … 110 109 */ 111 110 112 111 _Thread_Disable_dispatch(); 113 _Timer_ Process_ticks_chain();114 _Timer_ Process_seconds_chain();112 _Timer_Server_process_ticks_chain(); 113 _Timer_Server_process_seconds_chain(); 115 114 } 116 115 } 117 116 … … 244 243 } 245 244 246 245 /*PAGE 247 *248 * _Timer_Server_reset249 *250 * This routine resets the timers which determine when the Timer Server251 * will wake up next to service task-based timers.252 *253 * Input parameters:254 * do_ticks - TRUE indicates to process the ticks list255 * FALSE indicates to process the seconds list256 *257 * Output parameters: NONE258 */259 260 void _Timer_Server_reset(261 Timer_Server_reset_mode reset_mode262 )263 {264 Watchdog_Interval units;265 266 switch ( reset_mode ) {267 case TIMER_SERVER_RESET_TICKS:268 _Watchdog_Remove( &_Timer_Server->Timer );269 _Timer_Process_ticks_chain();270 if ( !_Chain_Is_empty( &_Timer_Ticks_chain ) ) {271 units = ((Watchdog_Control *)_Timer_Ticks_chain.first)->delta_interval;272 _Watchdog_Insert_ticks( &_Timer_Server->Timer, units );273 }274 break;275 case TIMER_SERVER_RESET_SECONDS:276 _Watchdog_Remove( &_Timer_Seconds_timer );277 _Timer_Process_seconds_chain();278 if ( !_Chain_Is_empty( &_Timer_Seconds_chain ) ) {279 units = ((Watchdog_Control *)_Timer_Seconds_chain.first)->delta_interval;280 _Watchdog_Insert_seconds( &_Timer_Seconds_timer, units );281 }282 break;283 }284 }285 286 /*PAGE287 246 * 288 * _Timer_Server_ Process_ticks_chain247 * _Timer_Server_process_ticks_chain 289 248 * 290 249 * This routine is responsible for adjusting the list of task-based 291 250 * interval timers to reflect the passage of time. … … 295 254 * Output parameters: NONE 296 255 */ 297 256 298 void _Timer_ Process_ticks_chain(void)257 void _Timer_Server_process_ticks_chain(void) 299 258 { 300 259 Watchdog_Interval snapshot; 301 260 Watchdog_Interval ticks; … … 312 271 313 272 /*PAGE 314 273 * 315 * _Timer_Server_ Process_seconds_chain274 * _Timer_Server_process_seconds_chain 316 275 * 317 276 * This routine is responsible for adjusting the list of task-based 318 277 * time of day timers to reflect the passage of time. … … 322 281 * Output parameters: NONE 323 282 */ 324 283 325 void _Timer_ Process_seconds_chain(void)284 void _Timer_Server_process_seconds_chain(void) 326 285 { 327 286 Watchdog_Interval snapshot; 328 287 Watchdog_Interval ticks; -
c/src/exec/rtems/src/timerserverfireafter.c
RCS file: /usr1/CVS/rtems/c/src/exec/rtems/src/timerserverfireafter.c,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 timerserverfireafter.c
69 69 the_timer->the_class = TIMER_INTERVAL_ON_TASK; 70 70 _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); 71 71 the_timer->Ticker.initial = ticks; 72 73 _Timer_Server_stop_ticks_timer(); 74 _Timer_Server_process_ticks_chain(); 72 75 _Watchdog_Insert( &_Timer_Ticks_chain, &the_timer->Ticker ); 73 _Timer_Server_reset( TIMER_SERVER_RESET_TICKS ); 76 _Timer_Server_reset_ticks_timer(); 77 74 78 _Thread_Enable_dispatch(); 75 79 return RTEMS_SUCCESSFUL; 76 80 } -
c/src/exec/rtems/src/timerserverfirewhen.c
RCS file: /usr1/CVS/rtems/c/src/exec/rtems/src/timerserverfirewhen.c,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 timerserverfirewhen.c
77 77 the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK; 78 78 _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); 79 79 the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch; 80 81 _Timer_Server_stop_seconds_timer(); 82 _Timer_Server_process_seconds_chain(); 80 83 _Watchdog_Insert( &_Timer_Seconds_chain, &the_timer->Ticker ); 81 _Timer_Server_reset( TIMER_SERVER_RESET_SECONDS ); 84 _Timer_Server_reset_seconds_timer(); 85 82 86 _Thread_Enable_dispatch(); 83 87 return RTEMS_SUCCESSFUL; 84 88 } -
c/src/tests/sptests/sp31/sp31.scn
RCS file: /usr1/CVS/rtems/c/src/tests/sptests/sp31/sp31.scn,v retrieving revision 1.1.2.1 diff -u -r1.1.2.1 sp31.scn
1 1 *** TEST 31 *** 2 2 INIT - rtems_timer_create - creating timer 1 3 3 INIT - timer 1 has id (0x14010001) 4 INIT - rtems_timer_create - creating timer 2 5 INIT - timer 2 has id (0x14010002) 4 6 TA1 - rtems_timer_ident - identing timer 1 5 7 TA1 - timer 1 has id (0x14010001) 6 TA1 - rtems_clock_get - 09:00:00 12/31/1988 8 TA1 - rtems_timer_ident - identing timer 2 9 TA1 - timer 2 has id (0x14010002) 10 TA1 - rtems_timer_server_fire_after - 1 second 11 TA1 - rtems_task_wake_after - 1/2 second 12 TA1 - rtems_timer_server_fire_after - timer 2 in 1/2 second 13 TA1 - rtems_timer_cancel - timer 1 14 TA1 - rtems_timer_cancel - timer 2 15 TA1 - rtems_timer_server_fire_after - timer 1 in 30 seconds 16 TA1 - rtems_timer_server_fire_after - timer 2 in 60 seconds 17 Timer 1 scheduled for 3050 ticks since boot 18 Timer Server scheduled for 3050 ticks since boot 19 TA1 - rtems_task_wake_after - 1 second 20 TA1 - rtems_timer_server_fire_after - timer 2 in 60 seconds 21 Timer 1 scheduled for 3050 ticks since boot 22 Timer Server scheduled for 3050 ticks since boot 23 TA1 - rtems_task_wake_after - 1 second 24 TA1 - rtems_timer_server_fire_after - timer 2 in 60 seconds 25 Timer 1 scheduled for 3050 ticks since boot 26 Timer Server scheduled for 3050 ticks since boot 27 TA1 - rtems_timer_cancel - timer 1 28 TA1 - rtems_timer_cancel - timer 2 29 TA1 - rtems_clock_get - 09:00:02 12/31/1988 7 30 TA1 - rtems_timer_server_fire_after - timer 1 in 3 seconds 8 31 TA1 - rtems_task_suspend( RTEMS_SELF ) 9 TA1 - rtems_clock_get - 09:00:0 312/31/198832 TA1 - rtems_clock_get - 09:00:05 12/31/1988 10 33 TA1 - rtems_timer_server_fire_after - timer 1 in 3 seconds 11 34 TA1 - rtems_task_wake_after - 1 second 12 TA1 - rtems_clock_get - 09:00:0 412/31/198835 TA1 - rtems_clock_get - 09:00:06 12/31/1988 13 36 TA1 - rtems_timer_reset - timer 1 14 37 TA1 - rtems_task_suspend( RTEMS_SELF ) 15 TA1 - rtems_clock_get - 09:00:0 712/31/198838 TA1 - rtems_clock_get - 09:00:09 12/31/1988 16 39 <pause> 17 40 TA1 - rtems_timer_server_fire_after - timer 1 in 3 seconds 18 41 TA1 - rtems_timer_cancel - timer 1 … … 26 49 TA1 - rtems_timer_cancel - timer 1 27 50 TA1 - rtems_task_wake_after - YIELD (only task at priority) 28 51 TA1 - timer_deleting - timer 1 29 *** END OF TEST 31 *** 52 *** END OF TEST 31 *** -
c/src/tests/sptests/sp31/task1.c
RCS file: /usr1/CVS/rtems/c/src/tests/sptests/sp31/task1.c,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 task1.c
15 15 * found in the file LICENSE in this distribution or at 16 16 * http://www.OARcorp.com/rtems/license.html. 17 17 * 18 * $Id: task1.c,v 1. 1.2.2 2002/01/29 18:20:46joel Exp $18 * $Id: task1.c,v 1.3 2002/01/29 18:20:59 joel Exp $ 19 19 */ 20 20 21 21 #include "system.h" 22 22 23 volatile int TSR_fired; 24 25 rtems_timer_service_routine Should_not_fire_TSR( 26 rtems_id ignored_id, 27 void *ignored_address 28 ) 29 { 30 TSR_fired = 1; 31 } 32 23 33 rtems_task Task_1( 24 34 rtems_task_argument argument 25 35 ) … … 42 52 directive_failed( status, "rtems_timer_ident" ); 43 53 printf( "TA1 - timer 2 has id (0x%x)\n", tmid2 ); 44 54 55 /* make sure insertion does not unintentionally fire a timer per PR147 */ 56 57 TSR_fired = 0; 58 59 puts( "TA1 - rtems_timer_server_fire_after - 1 second" ); 60 status = rtems_timer_server_fire_after( 61 tmid, TICKS_PER_SECOND, Should_not_fire_TSR, NULL ); 62 directive_failed( status, "rtems_timer_server_fire_after" ); 63 64 puts( "TA1 - rtems_task_wake_after - 1/2 second" ); 65 status = rtems_task_wake_after( TICKS_PER_SECOND / 2 ); 66 directive_failed( status, "rtems_timer_server_fire_after" ); 67 68 directive_failed( status, "rtems_timer_server_fire_after" ); 69 puts( "TA1 - rtems_timer_server_fire_after - timer 2 in 1/2 second" ); 70 status = rtems_timer_server_fire_after( 71 tmid2, TICKS_PER_SECOND / 2, Should_not_fire_TSR, NULL ); 72 directive_failed( status, "rtems_timer_server_fire_after" ); 73 74 if ( TSR_fired ) { 75 puts( "TA1 - TSR fired and should not have!" ); 76 exit(1); 77 } 78 79 puts( "TA1 - rtems_timer_cancel - timer 1" ); 80 status = rtems_timer_cancel( tmid ); 81 directive_failed( status, "rtems_timer_cancel" ); 82 83 puts( "TA1 - rtems_timer_cancel - timer 2" ); 84 status = rtems_timer_cancel( tmid2 ); 85 directive_failed( status, "rtems_timer_cancel" ); 86 87 45 88 /* now check that rescheduling an active timer works OK. */ 46 89 puts( "TA1 - rtems_timer_server_fire_after - timer 1 in 30 seconds" ); 47 90 status = rtems_timer_server_fire_after(