$NetBSD: patch-db,v 1.1 1999/04/28 23:57:04 rvb Exp $ diff -u /usr/pkgsrc/net/coda-5.2.2/coda-src/rpc2/host.c ./coda-src/rpc2/host.c --- /usr/pkgsrc/net/coda-5.2.2/coda-src/rpc2/host.c Mon Apr 19 20:02:40 1999 +++ ./coda-src/rpc2/host.c Mon Apr 26 14:05:08 1999 @@ -148,9 +148,8 @@ he->RTT = 0; he->RTTVar = 0; - he->BW = 1000 << RPC2_BW_SHIFT; - he->BWVar = 0 << RPC2_BWVAR_SHIFT; - he->LastBytes = 0; + he->BR = 1000 << RPC2_BR_SHIFT; + he->BRVar = 0; /* insert into hash table */ bucket = HASHHOST(&he->Host); @@ -302,7 +301,8 @@ rpc2_UpdateEstimates(host, &tv, Bytes); } -/* Here we update the RTT and Bandwidth estimates, +/* Here we update the RTT and Bandwidth (or more precise byterate in ns per + * byte) estimates, * ElapsedTime is the observed roundtrip-time in milliseconds * Bytes is the number of bytes transferred */ void rpc2_UpdateEstimates(struct HEntry *host, struct timeval *elapsed, @@ -310,7 +310,7 @@ { unsigned long elapsed_us; long eRTT; /* estimated null roundtrip time */ - long eBW; /* estimated bandwidth */ + long eBR; /* estimated byterate (ns/B) */ unsigned long eU; /* temporary unsigned variable */ long eL; /* temporary signed variable */ @@ -332,41 +332,38 @@ /* get the estimated rtt */ eRTT = host->RTT >> RPC2_RTT_SHIFT; - if (elapsed_us > eRTT) - { - eU = elapsed_us - eRTT; - - /* eBW = ( eU * 1000 ) / Bytes ; */ - eBW = ((eU << 7) / Bytes) << 3; + if (elapsed_us > eRTT) eU = elapsed_us - eRTT; + else eU = 0; - /* This is a hack to compensate for slow WinNT servers */ - /* HACK! to avoid small packets with unusually long RTT's to have a - * negative effect on the BW estimate, we avoid using measurements - * from small packets with a BW smaller than 1/2 the estimated BW */ - if (eBW > (host->BW >> (RPC2_BW_SHIFT - 1)) && Bytes < 512) eBW = 0; - else eBW -= (host->BW >> RPC2_BW_SHIFT); - /* HACK! */ + /* eBR = ( eU * 1000 ) / Bytes ; */ + eBR = ((eU << 7) / Bytes) << 3; + eBR -= (host->BR >> RPC2_BR_SHIFT); + + /* HACK! to avoid small packets with RTT's that are not within the current + * window of variance to have a strong effect on the byterate estimate, we + * halve the difference of the new measurement, if it falls outside of the + * variance window */ + if (eBR > (host->BRVar >> RPC2_BRVAR_SHIFT)) eBR >>= 1; + else if (eBR < -(host->BRVar >> RPC2_BRVAR_SHIFT)) eBR >>= 1; + /* HACK! */ + + host->BR += eBR; - host->BW += eBW; - - if (eBW < 0) eBW = -eBW; - } - else eBW = 0; + if (eBR < 0) eBR = -eBR; - /* Invariant: eBW contains the absolute difference between the previous - * calculated bandwidth and the new measurement */ + /* Invariant: eBR contains the absolute difference between the previous + * calculated byterate and the new measurement */ - eBW -= (host->BWVar >> RPC2_BWVAR_SHIFT); - host->BWVar += eBW; + eBR -= (host->BRVar >> RPC2_BRVAR_SHIFT); + host->BRVar += eBR; /* get a new RTT estimate in elapsed_us */ - /* from here on eBW contains a lower estimate on the effective - * bandwidth, eRTT will contain a updated RTT estimate */ - eBW = (host->BW >> RPC2_BW_SHIFT) + - ((host->BWVar >> RPC2_BWVAR_SHIFT) >> 1); + /* from here on eBR contains a lower estimate on the effective + * byterate, eRTT will contain a updated RTT estimate */ + eBR = (host->BR >> RPC2_BR_SHIFT) + ((host->BR >> RPC2_BRVAR_SHIFT) >> 1); - /* eU = ( eBW * Bytes ) / 1000 ; */ - eU = ((eBW >> 3) * Bytes) >> 7; + /* eU = ( eBR * Bytes ) / 1000 ; */ + eU = ((eBR >> 4) * Bytes) >> 6; if (elapsed_us > eU) eL = elapsed_us - eU; else eL = 0; @@ -381,13 +378,11 @@ eL -= (host->RTTVar >> RPC2_RTTVAR_SHIFT); host->RTTVar += eL; - host->LastBytes = Bytes; - say(0, RPC2_DebugLevel, - "Est: %s %4ld.%06lu/%-5lu RTT:%lu/%lu us BW:%lu/%lu B/s\n", + "Est: %s %4ld.%06lu/%-5lu RTT:%lu/%lu us BR:%lu/%lu ns/B\n", inet_ntoa(host->Host), elapsed->tv_sec, elapsed->tv_usec, Bytes, host->RTT>>RPC2_RTT_SHIFT, host->RTTVar>>RPC2_RTTVAR_SHIFT, - (1<<30)/(host->BW>>RPC2_BW_SHIFT), host->BWVar>>RPC2_BWVAR_SHIFT); + (host->BR>>RPC2_BR_SHIFT), host->BRVar>>RPC2_BRVAR_SHIFT); return; } @@ -396,7 +391,7 @@ struct timeval *tv) { unsigned long rto; - long effBW; + long effBR; int i, shift = 1; if (!host || !tv) return; @@ -413,11 +408,11 @@ * RTT estimate (it is latency estimate), we have to add in the time to * send our packet into the estimated RTO */ - effBW = (host->BW >> RPC2_BW_SHIFT); - // - ((host->BWVar >> RPC2_BWVAR_SHIFT) >> 1); + effBR = (host->BR >> RPC2_BR_SHIFT); + // - ((host->BRVar >> RPC2_BRVAR_SHIFT) >> 1); - /* rto += ( effBW * Bytes ) / 1000 ; */ - rto += ((effBW >> 3) * Bytes) >> 7; + /* rto += ( effBR * Bytes ) / 1000 ; */ + rto += ((effBR >> 3) * Bytes) >> 7; /* minimum bound for rtt estimates to compensate for scheduling etc. */ if (rto < RPC2_MINRTO) rto = RPC2_MINRTO; @@ -446,18 +441,40 @@ return(RPC2_SUCCESS); } -int RPC2_GetBandwidth(RPC2_Handle handle, unsigned long *BW, - unsigned long *BWvar) +int RPC2_GetBandwidth(RPC2_Handle handle, unsigned long *BWlow, + unsigned long *BWavg, unsigned long *BWhigh) { struct CEntry *ce; + unsigned long BR, BRVar, tBR; ce = rpc2_GetConn(handle); - if (ce == NULL) - return(RPC2_NOCONNECTION); + if (ce == NULL) return(RPC2_NOCONNECTION); - /* Adding 1 to the BW to avoid divide by zero errors --JH */ - if (BW) *BW = 1000000000 / ((ce->HostInfo->BW >> RPC2_BW_SHIFT) + 1); - if (BWvar) *BWvar = ce->HostInfo->BWVar >> RPC2_BWVAR_SHIFT; + BR = ce->HostInfo->BR >> RPC2_BR_SHIFT; + BRVar = ce->HostInfo->BRVar >> RPC2_BRVAR_SHIFT; + + if (BWlow) { + tBR = BR + BRVar; + /* Need at least 1 to avoid divide by zero errors --JH */ + if (!tBR) tBR = 1; + + *BWlow = 1000000000 / tBR; + } + if (BWavg) { + tBR = BR; + /* Need at least 1 to avoid divide by zero errors --JH */ + if (!tBR) tBR = 1; + + *BWavg = 1000000000 / tBR; + } + if (BWhigh) { + if (BR > BRVar) + tBR = BR - BRVar; + else + tBR = 1; + + *BWhigh = 1000000000 / tBR; + } return(RPC2_SUCCESS); }