david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[retry] Use a separate flag to indicate that a retry timer is running

Using start==0 to indicate a stopped timer is dangerous, because 0 is a
valid value for the current tick counter.
This commit is contained in:
Michael Brown 2008-10-12 15:04:37 +01:00
parent 941b4c2adb
commit f945d6d201
2 changed files with 12 additions and 9 deletions

View File

@ -19,6 +19,8 @@
struct retry_timer { struct retry_timer {
/** List of active timers */ /** List of active timers */
struct list_head list; struct list_head list;
/** Timer is currently running */
unsigned int running;
/** Timeout value (in ticks) */ /** Timeout value (in ticks) */
unsigned long timeout; unsigned long timeout;
/** Minimum timeout value (in ticks) /** Minimum timeout value (in ticks)
@ -31,10 +33,7 @@ struct retry_timer {
* A value of zero means "use default timeout." * A value of zero means "use default timeout."
*/ */
unsigned long max_timeout; unsigned long max_timeout;
/** Start time (in ticks) /** Start time (in ticks) */
*
* A start time of zero indicates a stopped timer.
*/
unsigned long start; unsigned long start;
/** Retry count */ /** Retry count */
unsigned int count; unsigned int count;
@ -74,7 +73,7 @@ static inline void start_timer_nodelay ( struct retry_timer *timer ) {
*/ */
static inline __attribute__ (( always_inline )) unsigned long static inline __attribute__ (( always_inline )) unsigned long
timer_running ( struct retry_timer *timer ) { timer_running ( struct retry_timer *timer ) {
return ( timer->start ); return ( timer->running );
} }
#endif /* _GPXE_RETRY_H */ #endif /* _GPXE_RETRY_H */

View File

@ -55,9 +55,10 @@ static LIST_HEAD ( timers );
* be stopped and the timer's callback function will be called. * be stopped and the timer's callback function will be called.
*/ */
void start_timer ( struct retry_timer *timer ) { void start_timer ( struct retry_timer *timer ) {
if ( ! timer_running ( timer ) ) if ( ! timer->running )
list_add ( &timer->list, &timers ); list_add ( &timer->list, &timers );
timer->start = currticks(); timer->start = currticks();
timer->running = 1;
/* 0 means "use default timeout" */ /* 0 means "use default timeout" */
if ( timer->min_timeout == 0 ) if ( timer->min_timeout == 0 )
@ -82,6 +83,8 @@ void start_timer ( struct retry_timer *timer ) {
void start_timer_fixed ( struct retry_timer *timer, unsigned long timeout ) { void start_timer_fixed ( struct retry_timer *timer, unsigned long timeout ) {
start_timer ( timer ); start_timer ( timer );
timer->timeout = timeout; timer->timeout = timeout;
DBG2 ( "Timer %p expiry time changed to %ld\n",
timer, ( timer->start + timer->timeout ) );
} }
/** /**
@ -97,12 +100,12 @@ void stop_timer ( struct retry_timer *timer ) {
unsigned long runtime; unsigned long runtime;
/* If timer was already stopped, do nothing */ /* If timer was already stopped, do nothing */
if ( ! timer_running ( timer ) ) if ( ! timer->running )
return; return;
list_del ( &timer->list ); list_del ( &timer->list );
runtime = ( now - timer->start ); runtime = ( now - timer->start );
timer->start = 0; timer->running = 0;
DBG2 ( "Timer %p stopped at time %ld (ran for %ld)\n", DBG2 ( "Timer %p stopped at time %ld (ran for %ld)\n",
timer, now, runtime ); timer, now, runtime );
@ -144,8 +147,9 @@ static void timer_expired ( struct retry_timer *timer ) {
/* Stop timer without performing RTT calculations */ /* Stop timer without performing RTT calculations */
DBG2 ( "Timer %p stopped at time %ld on expiry\n", DBG2 ( "Timer %p stopped at time %ld on expiry\n",
timer, currticks() ); timer, currticks() );
assert ( timer->running );
list_del ( &timer->list ); list_del ( &timer->list );
timer->start = 0; timer->running = 0;
timer->count++; timer->count++;
/* Back off the timeout value */ /* Back off the timeout value */