mirror of
https://github.com/xcat2/xNBA.git
synced 2025-04-18 11:09:26 +00:00
Towards an RFC2988-compliant timer.
This commit is contained in:
parent
f0718d562f
commit
c3a4f3c5da
@ -17,6 +17,8 @@ struct retry_timer {
|
||||
unsigned long timeout;
|
||||
/** Start time (in ticks) */
|
||||
unsigned long start;
|
||||
/** Retry count */
|
||||
unsigned int count;
|
||||
/** Timer expired callback
|
||||
*
|
||||
* @v timer Retry timer
|
||||
|
@ -29,6 +29,11 @@
|
||||
*
|
||||
* A retry timer is a binary exponential backoff timer. It can be
|
||||
* used to build automatic retransmission into network protocols.
|
||||
*
|
||||
* This implementation of the timer is designed to satisfy RFC 2988
|
||||
* and therefore be usable as a TCP retransmission timer.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/** Default timeout value */
|
||||
@ -94,14 +99,41 @@ void stop_timer ( struct retry_timer *timer ) {
|
||||
* t := ( 7 t / 8 ) + ( r / 2 )
|
||||
*
|
||||
*/
|
||||
timer->timeout -= ( timer->timeout >> 3 );
|
||||
timer->timeout += ( runtime >> 1 );
|
||||
if ( timer->timeout != old_timeout ) {
|
||||
DBG ( "Timer updated to %dms\n",
|
||||
( ( 1000 * timer->timeout ) / TICKS_PER_SEC ) );
|
||||
if ( timer->count ) {
|
||||
timer->count--;
|
||||
} else {
|
||||
timer->timeout -= ( timer->timeout >> 3 );
|
||||
timer->timeout += ( runtime >> 1 );
|
||||
if ( timer->timeout != old_timeout ) {
|
||||
DBG ( "Timer updated to %dms\n",
|
||||
( ( 1000 * timer->timeout ) / TICKS_PER_SEC ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle expired timer
|
||||
*
|
||||
* @v timer Retry timer
|
||||
*/
|
||||
static void timer_expired ( struct retry_timer *timer ) {
|
||||
int fail;
|
||||
|
||||
/* Stop timer without performing RTT calculations */
|
||||
list_del ( &timer->list );
|
||||
timer->count++;
|
||||
|
||||
/* Back off the timeout value */
|
||||
timer->timeout <<= 1;
|
||||
if ( ( fail = ( timer->timeout > MAX_TIMEOUT ) ) )
|
||||
timer->timeout = MAX_TIMEOUT;
|
||||
DBG ( "Timer backed off to %dms\n",
|
||||
( ( 1000 * timer->timeout ) / TICKS_PER_SEC ) );
|
||||
|
||||
/* Call expiry callback */
|
||||
timer->expired ( timer, fail );
|
||||
}
|
||||
|
||||
/**
|
||||
* Single-step the retry timer list
|
||||
*
|
||||
@ -112,22 +144,11 @@ static void retry_step ( struct process *process ) {
|
||||
struct retry_timer *tmp;
|
||||
unsigned long now = currticks();
|
||||
unsigned long used;
|
||||
int fail;
|
||||
|
||||
list_for_each_entry_safe ( timer, tmp, &timers, list ) {
|
||||
used = ( now - timer->start );
|
||||
if ( used >= timer->timeout ) {
|
||||
/* Stop timer without performing RTT calculations */
|
||||
list_del ( &timer->list );
|
||||
/* Back off the timeout value */
|
||||
timer->timeout <<= 1;
|
||||
if ( ( fail = ( timer->timeout > MAX_TIMEOUT ) ) )
|
||||
timer->timeout = MAX_TIMEOUT;
|
||||
DBG ( "Timer backed off to %dms\n",
|
||||
( ( 1000 * timer->timeout ) / TICKS_PER_SEC ) );
|
||||
/* Call expiry callback */
|
||||
timer->expired ( timer, fail );
|
||||
}
|
||||
if ( used >= timer->timeout )
|
||||
timer_expired ( timer );
|
||||
}
|
||||
|
||||
schedule ( process );
|
||||
|
Loading…
x
Reference in New Issue
Block a user