#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. | |
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 MIN_TIMEOUT 7 |
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static LIST_HEAD | ( | timers | ) | [static] |
List of running timers.
| void start_timer | ( | struct retry_timer * | timer | ) |
Start timer.
| timer | Retry timer |
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.
| 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.
| timer | Retry timer |
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.
| 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 }
Single-step the retry timer list.
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 }
| struct process retry_process __permanent_process |
Initial value:
{
.list = LIST_HEAD_INIT ( retry_process.list ),
.step = retry_step,
}
1.5.7.1