1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-04 10:38:13 +00:00

add new compile-time throttle options suggested by persept

This commit is contained in:
Charles Kerr 2008-09-18 03:55:31 +00:00
parent 089054957c
commit b5efa86ad7
3 changed files with 46 additions and 42 deletions

View file

@ -128,8 +128,8 @@ struct tr_peerMgr
tr_ptrArray * torrents; /* Torrent */ tr_ptrArray * torrents; /* Torrent */
tr_ptrArray * incomingHandshakes; /* tr_handshake */ tr_ptrArray * incomingHandshakes; /* tr_handshake */
tr_timer * bandwidthTimer; tr_timer * bandwidthTimer;
double rateHistory[2][BANDWIDTH_PULSES_PER_SECOND]; double rateHistory[2][BANDWIDTH_PULSE_HISTORY];
double globalPoolHistory[2][BANDWIDTH_PULSES_PER_SECOND]; double globalPoolHistory[2][BANDWIDTH_PULSE_HISTORY];
}; };
#define tordbg(t, fmt...) \ #define tordbg(t, fmt...) \
@ -1476,15 +1476,16 @@ tr_peerMgrGetRate( const tr_peerMgr * manager,
tr_direction direction ) tr_direction direction )
{ {
int i; int i;
double rate = 0; double bytes = 0;
assert( manager != NULL ); assert( manager != NULL );
assert( direction==TR_UP || direction==TR_DOWN ); assert( direction==TR_UP || direction==TR_DOWN );
for( i=0; i<BANDWIDTH_PULSES_PER_SECOND; ++i ) for( i=0; i<BANDWIDTH_PULSE_HISTORY; ++i )
rate += manager->rateHistory[direction][i]; bytes += manager->rateHistory[direction][i];
return rate / 1024.0; return ( BANDWIDTH_PULSES_PER_SECOND * bytes )
/ ( BANDWIDTH_PULSE_HISTORY * 1024 );
} }
float* float*
@ -2016,49 +2017,49 @@ reconnectPulse( void * vtorrent )
static double static double
allocateHowMuch( double desiredAvgKB, allocateHowMuch( double desiredAvgKB,
const double * history, const double * history )
int pulseNumber )
{ {
int i;
int oldest = ( pulseNumber + 1 ) % BANDWIDTH_PULSES_PER_SECOND;
const double baseline = desiredAvgKB * 1024.0 / BANDWIDTH_PULSES_PER_SECOND; const double baseline = desiredAvgKB * 1024.0 / BANDWIDTH_PULSES_PER_SECOND;
const double min = baseline * 0.66; const double min = baseline * 0.66;
const double max = baseline * 1.33; const double max = baseline * 1.33;
double bytes; int i;
double usedBytes;
double n;
double clamped;
bytes = desiredAvgKB * 1024.0; for( usedBytes=i=0; i<BANDWIDTH_PULSE_HISTORY; ++i )
for( i=0; i<BANDWIDTH_PULSES_PER_SECOND; ++i ) usedBytes += history[i];
if( i != oldest )
bytes -= history[i];
/* clamp the return value to lessen any oscillation */ n = ( desiredAvgKB * 1024.0 ) * ( BANDWIDTH_PULSE_HISTORY + 1.0 ) / BANDWIDTH_PULSES_PER_SECOND - usedBytes;
bytes = MAX( bytes, min );
bytes = MIN( bytes, max ); /* clamp the return value to lessen oscillation */
return bytes; clamped = n;
clamped = MAX( clamped, min );
clamped = MIN( clamped, max );
/*fprintf( stderr, "desiredAvgKB is %.2f, rate is %.2f, allocating %.2f (%.2f)\n", desiredAvgKB, ((usedBytes*BANDWIDTH_PULSES_PER_SECOND)/BANDWIDTH_PULSE_HISTORY)/1024.0, clamped/1024.0, n/1024.0 );*/
return clamped;
} }
/** /**
* Distirbutes a fixed amount of bandwidth among a set of peers. * Distributes a fixed amount of bandwidth among a set of peers.
* *
* @param peerArray peers whose client-to-peer bandwidth will be adjusted * @param peerArray peers whose client-to-peer bandwidth will be set
* @param direction whether to allocate upload or download bandwidth * @param direction whether to allocate upload or download bandwidth
* @param history recent bandwidth history for these peers * @param history recent bandwidth history for these peers
* @param pulseNumber index of the current pulse in the history array
* @param desiredAvgKB overall bandwidth goal for this set of peers * @param desiredAvgKB overall bandwidth goal for this set of peers
*/ */
static void static void
setPeerBandwidth( tr_ptrArray * peerArray, setPeerBandwidth( tr_ptrArray * peerArray,
const tr_direction direction, const tr_direction direction,
const double * history, const double * history,
int pulseNumber,
double desiredAvgKB ) double desiredAvgKB )
{ {
const int peerCount = tr_ptrArraySize( peerArray ); const int peerCount = tr_ptrArraySize( peerArray );
tr_peer ** peers = (tr_peer**) tr_ptrArrayBase( peerArray ); const double bytes = allocateHowMuch( desiredAvgKB, history );
tr_peer ** candidates = tr_new( tr_peer*, peerCount );
const double bytes = allocateHowMuch( desiredAvgKB, history, pulseNumber );
const double welfareBytes = MIN( 2048, bytes * 0.2 ); const double welfareBytes = MIN( 2048, bytes * 0.2 );
const double meritBytes = MAX( 0, bytes - welfareBytes ); const double meritBytes = MAX( 0, bytes - welfareBytes );
tr_peer ** peers = (tr_peer**) tr_ptrArrayBase( peerArray );
tr_peer ** candidates = tr_new( tr_peer*, peerCount );
int i; int i;
int candidateCount; int candidateCount;
double welfare; double welfare;
@ -2095,10 +2096,10 @@ setPeerBandwidth( tr_ptrArray * peerArray,
static size_t static size_t
countHandshakeBandwidth( tr_ptrArray * handshakes, tr_direction direction ) countHandshakeBandwidth( tr_ptrArray * handshakes, tr_direction direction )
{ {
int i;
size_t total = 0;
const int n = tr_ptrArraySize( handshakes ); const int n = tr_ptrArraySize( handshakes );
for( i=0; i<n; ++i ) { int i;
size_t total;
for( i=total=0; i<n; ++i ) {
tr_peerIo * io = tr_handshakeGetIO( tr_ptrArrayNth( handshakes, i ) ); tr_peerIo * io = tr_handshakeGetIO( tr_ptrArrayNth( handshakes, i ) );
total += tr_peerIoGetBandwidthUsed( io, direction ); total += tr_peerIoGetBandwidthUsed( io, direction );
} }
@ -2108,10 +2109,10 @@ countHandshakeBandwidth( tr_ptrArray * handshakes, tr_direction direction )
static size_t static size_t
countPeerBandwidth( tr_ptrArray * peers, tr_direction direction ) countPeerBandwidth( tr_ptrArray * peers, tr_direction direction )
{ {
int i;
size_t total = 0;
const int n = tr_ptrArraySize( peers ); const int n = tr_ptrArraySize( peers );
for( i=0; i<n; ++i ) int i;
size_t total;
for( i=total=0; i<n; ++i )
{ {
tr_peer * peer = tr_ptrArrayNth( peers, i ); tr_peer * peer = tr_ptrArrayNth( peers, i );
total += tr_peerIoGetBandwidthUsed( peer->io, direction ); total += tr_peerIoGetBandwidthUsed( peer->io, direction );
@ -2122,8 +2123,8 @@ countPeerBandwidth( tr_ptrArray * peers, tr_direction direction )
static void static void
givePeersUnlimitedBandwidth( tr_ptrArray * peers, tr_direction direction ) givePeersUnlimitedBandwidth( tr_ptrArray * peers, tr_direction direction )
{ {
int i;
const int n = tr_ptrArraySize( peers ); const int n = tr_ptrArraySize( peers );
int i;
for( i=0; i<n; ++i ) for( i=0; i<n; ++i )
{ {
tr_peer * peer = tr_ptrArrayNth( peers, i ); tr_peer * peer = tr_ptrArrayNth( peers, i );
@ -2134,8 +2135,8 @@ givePeersUnlimitedBandwidth( tr_ptrArray * peers, tr_direction direction )
static void static void
pumpAllPeers( tr_peerMgr * mgr ) pumpAllPeers( tr_peerMgr * mgr )
{ {
int i, j;
const int torrentCount = tr_ptrArraySize( mgr->torrents ); const int torrentCount = tr_ptrArraySize( mgr->torrents );
int i, j;
for( i=0; i<torrentCount; ++i ) for( i=0; i<torrentCount; ++i )
{ {
Torrent * t = tr_ptrArrayNth( mgr->torrents, i ); Torrent * t = tr_ptrArrayNth( mgr->torrents, i );
@ -2196,7 +2197,6 @@ allocateBandwidth( tr_peerMgr * mgr,
setPeerBandwidth( t->peers, direction, setPeerBandwidth( t->peers, direction,
t->tor->rateHistory[direction], t->tor->rateHistory[direction],
pulseNumber,
tr_torrentGetSpeedLimit( t->tor, tr_torrentGetSpeedLimit( t->tor,
direction ) ); direction ) );
break; break;
@ -2226,7 +2226,6 @@ allocateBandwidth( tr_peerMgr * mgr,
else else
setPeerBandwidth( globalPool, direction, setPeerBandwidth( globalPool, direction,
mgr->globalPoolHistory[direction], mgr->globalPoolHistory[direction],
pulseNumber,
tr_sessionGetSpeedLimit( session, direction ) ); tr_sessionGetSpeedLimit( session, direction ) );
/* now that we've allocated bandwidth, pump all the connected peers */ /* now that we've allocated bandwidth, pump all the connected peers */
@ -2245,7 +2244,7 @@ bandwidthPulse( void * vmgr )
managerLock( mgr ); managerLock( mgr );
/* keep track of how far we are into the cycle */ /* keep track of how far we are into the cycle */
if( ++mgr->bandwidthPulseNumber == BANDWIDTH_PULSES_PER_SECOND ) if( ++mgr->bandwidthPulseNumber == BANDWIDTH_PULSE_HISTORY )
mgr->bandwidthPulseNumber = 0; mgr->bandwidthPulseNumber = 0;
/* allocate the upload and download bandwidth */ /* allocate the upload and download bandwidth */

View file

@ -35,10 +35,15 @@
#endif #endif
#endif #endif
/** enum
* How frequently to reallocate peer bandwidth. {
*/ /* How frequently to reallocate peer bandwidth. */
#define BANDWIDTH_PULSES_PER_SECOND 5 BANDWIDTH_PULSES_PER_SECOND = 8,
/* HOw many pulses to remember for averaging the current speed */
BANDWIDTH_PULSE_HISTORY = ( BANDWIDTH_PULSES_PER_SECOND * 2 )
};
typedef enum { TR_NET_OK, TR_NET_ERROR, TR_NET_WAIT } tr_tristate_t; typedef enum { TR_NET_OK, TR_NET_ERROR, TR_NET_WAIT } tr_tristate_t;

View file

@ -180,7 +180,7 @@ struct tr_torrent
int uniqueId; int uniqueId;
double rateHistory[2][BANDWIDTH_PULSES_PER_SECOND]; double rateHistory[2][BANDWIDTH_PULSE_HISTORY];
}; };