retry.c File Reference

Retry timers. More...

#include <stddef.h>
#include <gpxe/timer.h>
#include <gpxe/list.h>
#include <gpxe/process.h>
#include <gpxe/init.h>
#include <gpxe/retry.h>

Go to the source code of this file.

Defines

#define MIN_TIMEOUT   7

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static LIST_HEAD (timers)
 List of running timers.
void start_timer (struct retry_timer *timer)
 Start timer.
void start_timer_fixed (struct retry_timer *timer, unsigned long timeout)
 Start timer with a specified fixed timeout.
void stop_timer (struct retry_timer *timer)
 Stop timer.
static void timer_expired (struct retry_timer *timer)
 Handle expired timer.
static void retry_step (struct process *process __unused)
 Single-step the retry timer list.

Variables

struct process retry_process __permanent_process
 Retry timer process.


Detailed Description

Retry timers.

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.

Definition in file retry.c.


Define Documentation

#define MIN_TIMEOUT   7

Definition at line 45 of file retry.c.

Referenced by start_timer().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static LIST_HEAD ( timers   )  [static]

List of running timers.

void start_timer ( struct retry_timer timer  ) 

Start timer.

Parameters:
timer Retry timer
This starts the timer running with the current timeout value. If stop_timer() is not called before the timer expires, the timer will be stopped and the timer's callback function will be called.

Definition at line 59 of file retry.c.

References currticks(), DBG2, DEFAULT_MIN_TIMEOUT, retry_timer::list, list_add, MIN_TIMEOUT, retry_timer::min_timeout, retry_timer::running, retry_timer::start, and retry_timer::timeout.

Referenced by aoe_send_command(), dhcp_tx(), dns_send_packet(), ib_mi_timer_expired(), ipv4_reassemble(), slam_master_timer_expired(), slam_slave_timer_expired(), slam_socket_deliver(), start_timer_fixed(), tcp_rx(), tcp_xmit(), and tftp_send_packet().

00059                                                {
00060         if ( ! timer->running )
00061                 list_add ( &timer->list, &timers );
00062         timer->start = currticks();
00063         timer->running = 1;
00064 
00065         /* 0 means "use default timeout" */
00066         if ( timer->min_timeout == 0 )
00067                 timer->min_timeout = DEFAULT_MIN_TIMEOUT;
00068         /* We must never be less than MIN_TIMEOUT under any circumstances */
00069         if ( timer->min_timeout < MIN_TIMEOUT )
00070                 timer->min_timeout = MIN_TIMEOUT;
00071         /* Honor user-specified minimum timeout */
00072         if ( timer->timeout < timer->min_timeout )
00073                 timer->timeout = timer->min_timeout;
00074 
00075         DBG2 ( "Timer %p started at time %ld (expires at %ld)\n",
00076                timer, timer->start, ( timer->start + timer->timeout ) );
00077 }

void start_timer_fixed ( struct retry_timer timer,
unsigned long  timeout 
)

Start timer with a specified fixed timeout.

Parameters:
timer Retry timer
timeout Timeout, in ticks

Definition at line 85 of file retry.c.

References DBG2, retry_timer::start, start_timer(), and retry_timer::timeout.

Referenced by slam_mc_socket_deliver(), slam_open(), and start_timer_nodelay().

00085                                                                             {
00086         start_timer ( timer );
00087         timer->timeout = timeout;
00088         DBG2 ( "Timer %p expiry time changed to %ld\n",
00089                timer, ( timer->start + timer->timeout ) );
00090 }

void stop_timer ( struct retry_timer timer  ) 

Stop timer.

Parameters:
timer Retry timer
This stops the timer and updates the timer's timeout value.

Definition at line 99 of file retry.c.

References retry_timer::count, currticks(), DBG, DBG2, retry_timer::list, list_del, retry_timer::running, retry_timer::start, and retry_timer::timeout.

Referenced by aoe_detach(), aoe_done(), aoe_rx_ata(), dhcp_finished(), dhcp_set_state(), dns_done(), dns_xfer_deliver_raw(), ib_destroy_madx(), slam_finished(), slam_mc_socket_deliver(), slam_socket_deliver(), tcp_close(), tcp_rx_ack(), tftp_done(), and tftp_send_packet().

00099                                               {
00100         unsigned long old_timeout = timer->timeout;
00101         unsigned long now = currticks();
00102         unsigned long runtime;
00103 
00104         /* If timer was already stopped, do nothing */
00105         if ( ! timer->running )
00106                 return;
00107 
00108         list_del ( &timer->list );
00109         runtime = ( now - timer->start );
00110         timer->running = 0;
00111         DBG2 ( "Timer %p stopped at time %ld (ran for %ld)\n",
00112                timer, now, runtime );
00113 
00114         /* Update timer.  Variables are:
00115          *
00116          *   r = round-trip time estimate (i.e. runtime)
00117          *   t = timeout value (i.e. timer->timeout)
00118          *   s = smoothed round-trip time
00119          *
00120          * By choice, we set t = 4s, i.e. allow for four times the
00121          * normal round-trip time to pass before retransmitting.
00122          *
00123          * We want to smooth according to s := ( 7 s + r ) / 8
00124          *
00125          * Since we don't actually store s, this reduces to
00126          * t := ( 7 t / 8 ) + ( r / 2 )
00127          *
00128          */
00129         if ( timer->count ) {
00130                 timer->count--;
00131         } else {
00132                 timer->timeout -= ( timer->timeout >> 3 );
00133                 timer->timeout += ( runtime >> 1 );
00134                 if ( timer->timeout != old_timeout ) {
00135                         DBG ( "Timer %p timeout updated to %ld\n",
00136                               timer, timer->timeout );
00137                 }
00138         }
00139 }

static void timer_expired ( struct retry_timer timer  )  [static]

Handle expired timer.

Parameters:
timer Retry timer

Definition at line 146 of file retry.c.

References assert, retry_timer::count, currticks(), DBG, DBG2, DEFAULT_MAX_TIMEOUT, retry_timer::expired, retry_timer::list, list_del, retry_timer::max_timeout, retry_timer::running, and retry_timer::timeout.

Referenced by retry_step().

00146                                                         {
00147         int fail;
00148 
00149         /* Stop timer without performing RTT calculations */
00150         DBG2 ( "Timer %p stopped at time %ld on expiry\n",
00151                timer, currticks() );
00152         assert ( timer->running );
00153         list_del ( &timer->list );
00154         timer->running = 0;
00155         timer->count++;
00156 
00157         /* Back off the timeout value */
00158         timer->timeout <<= 1;
00159         if ( timer->max_timeout == 0 ) /* 0 means "use default timeout" */
00160                 timer->max_timeout = DEFAULT_MAX_TIMEOUT;
00161         if ( ( fail = ( timer->timeout > timer->max_timeout ) ) )
00162                 timer->timeout = timer->max_timeout;
00163         DBG ( "Timer %p timeout backed off to %ld\n",
00164               timer, timer->timeout );
00165 
00166         /* Call expiry callback */
00167         timer->expired ( timer, fail ); 
00168 }

static void retry_step ( struct process *process  __unused  )  [static]

Single-step the retry timer list.

Parameters:
process Retry timer process

Definition at line 175 of file retry.c.

References currticks(), retry_timer::list, list_for_each_entry_safe, retry_timer::start, retry_timer::timeout, and timer_expired().

00175                                                             {
00176         struct retry_timer *timer;
00177         struct retry_timer *tmp;
00178         unsigned long now = currticks();
00179         unsigned long used;
00180 
00181         list_for_each_entry_safe ( timer, tmp, &timers, list ) {
00182                 used = ( now - timer->start );
00183                 if ( used >= timer->timeout )
00184                         timer_expired ( timer );
00185         }
00186 }


Variable Documentation

struct process retry_process __permanent_process

Initial value:

 {
        .list = LIST_HEAD_INIT ( retry_process.list ),
        .step = retry_step,
}
Retry timer process.

Definition at line 189 of file retry.c.


Generated on Tue Apr 6 20:01:55 2010 for gPXE by  doxygen 1.5.7.1