/* update our retransmission stuff */
/* new algorithms */
/*
Implementation of following algorithm is NECESSARY
(avoids congestion, improves performance)
Van Jacobson algorithm (from his book) :
Constants : alpha=1/8 beta=1/4 gamma=4 (for TCP)
RTT : Round Trip Time (time between sending and reply)
SRTT : Smoothed Round Trip Time (predicted RTT)
SRTT[K]=(1-alpha)*SRTT[K-1]+alpha*RTT[K]
ERR : Difference between prediction and reality
ERR[K]=RTT[K]-SRTT[K-1]
RTTVAR : Round Trip Time Variation (predicted error)
or SDEV : Smoothed Deviation
SDEV[K]=(1-beta)*SDEV[K-1]+beta*abs(ERR[K])
RTO : Retransmission Timeout
RTO[K]=SRTT[K]+gamma*SDEV[K]
Exponential smoothing algorithm (from rfc2988) :
1) G : timer granularity (<=100ms is better)
heartbeat : 2.5<2.5+G<3 seconds
2) First RTT measurement : R
SRTT=R
RTTVAR=R/2
RTO=SRTT+max(G,gamma*RTTVAR)
3) Next RTT measurements : R2
RTTVAR=(1-beta)*RTTVAR+beta*abs(SRTT-R2)
SRTT=(1-alpha)*SRTT+alpha*R2
(order is important)
4) if RTO<1s RTO=1s
5) if RTO>60s RTO=60s
Suggested sequence (from rfc2988) :
1) Start timeout detection with RTO
each time a packet containing data is sent
2) When all is done suspend timout detection
3) When ACK packet is received reset to RTO
4) If RTO timeout is detected, resend last packet,
double RTO value and detect next timout : RTO=RTO*2 (max 60s)
If happens too often, restart with first measurement R
*/
if (s->karn_count == 2) {
s->karn_count = 0;
#ifdef DEBUG
if (debug_on > 1 ) printf("finally got it safely zapped from %u to

?\n\r",s->unacked);
#endif
} else {
if ( unal2l(s->vj_last) ) {
// unnecessary to use unhappy || s->datalen )
if ((diffticks = set_ttimeout( 0 ) - unal2l(s->vj_last)) >= 0 ) {
#ifdef TRACECALLS
setlastcall("tcp_handler 6");
#endif
// we ignore the overnight case
diffticks -= (longword)( s->vj_sa >> 3 );
s->vj_sa += (int)diffticks;
if (diffticks < 0)
diffticks = - diffticks;
diffticks -= (s->vj_sd >> 2);
s->vj_sd += (int)diffticks;
if (s->vj_sa > MAXVJSA) s->vj_sa = MAXVJSA;
if (s->vj_sd > MAXVJSD) s->vj_sd = MAXVJSD;
#ifdef TRACECALLS
setlastcall("tcp_handler 7");
#endif
}
// only recompute rtt hence rto after success
s->rto = 1 + (((s->vj_sa >> 2) + (s->vj_sd)) >> 1);
#ifdef DEBUG
if (debug_on > 1 ) printf("rto %u sa %u sd %u cwindow %u wwindow %u unacked %u\n",
s->rto, s->vj_sa, s->vj_sd, s->cwindow, s->wwindow, s->unacked );
#endif
}
s->karn_count = 0;
if ( s->wwindow != 255 ) {
if ( s->wwindow++ >= s->cwindow ) {
if ( s->cwindow != 255 )
s->cwindow ++;
}
s->wwindow = 0;
}
}
// all new
scheduleto = set_ttimeout( s->rto + 2 );
if ( unal2l(s->rtt_time) < scheduleto )
{
movl2unal(scheduleto,s->rtt_time);
}
#ifdef TRACECALLS
setlastcall("tcp_handler 8");
#endif
switch ( s->state ) {
(It's much cleaner on PS2, so sometimes, thx to a unique source that recompiles on pc0, xb1 & ps2, I could debug on PS2 where I can catch the faulty line in source and so get it fixed for other platforms. So I never tried to improve things on xbox1. When I studied it I instantly gave up because you need to play with stack structure to recover from bad crash and I don't know it well enough on xbox1...)
The setlastcall allows on ps2 to have the name of the last executed section before crash.
3) XSleep erases things...
A hang in xbox1 may often erase everything on screen for sure. For XSleep I don't know.
If pbkit is activated it can do screen swaps at next VBL unless you ask to show the debug screen.
If there is no hang, then you should be able to control what is displayed by using correctly pbkit functions. The top of debug screen may be overlapped by normal screens (so if they get cleaned you lose your debugging text). Try to display text on the half top of the screen then display your debugging text.
You can always ignore pbkit and not activate it and have the standard openxdk behaviour regarding text.
4) Takes a lots of time...
But in my case (several months) it was worthy because I got instantly a stack under control running on SEVERAL platforms with same source to maintain.