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:
parent
089054957c
commit
b5efa86ad7
3 changed files with 46 additions and 42 deletions
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,7 @@ struct tr_torrent
|
||||||
|
|
||||||
int uniqueId;
|
int uniqueId;
|
||||||
|
|
||||||
double rateHistory[2][BANDWIDTH_PULSES_PER_SECOND];
|
double rateHistory[2][BANDWIDTH_PULSE_HISTORY];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue