mirror of
https://github.com/transmission/transmission
synced 2024-12-26 09:37:56 +00:00
(libT) #1468: speed display is very jumpy
This commit is contained in:
parent
0bcff74d52
commit
9571f3b714
3 changed files with 104 additions and 136 deletions
|
@ -30,7 +30,6 @@
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "peer-io.h"
|
#include "peer-io.h"
|
||||||
#include "ratecontrol.h"
|
|
||||||
#include "trevent.h"
|
#include "trevent.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
@ -72,9 +71,8 @@ addPacketOverhead( size_t d )
|
||||||
|
|
||||||
struct tr_bandwidth
|
struct tr_bandwidth
|
||||||
{
|
{
|
||||||
unsigned int isUnlimited : 1;
|
unsigned int isUnlimited : 1;
|
||||||
size_t bytesUsed;
|
size_t bytesLeft;
|
||||||
size_t bytesLeft;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tr_datatype
|
struct tr_datatype
|
||||||
|
@ -220,7 +218,6 @@ didWriteWrapper( struct bufferevent * e,
|
||||||
{
|
{
|
||||||
struct tr_bandwidth * b = &io->bandwidth[TR_UP];
|
struct tr_bandwidth * b = &io->bandwidth[TR_UP];
|
||||||
b->bytesLeft -= MIN( b->bytesLeft, n );
|
b->bytesLeft -= MIN( b->bytesLeft, n );
|
||||||
b->bytesUsed += n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( io->didWrite )
|
if( io->didWrite )
|
||||||
|
@ -256,8 +253,7 @@ canReadWrapper( struct bufferevent * e,
|
||||||
const size_t n = addPacketOverhead( payload );
|
const size_t n = addPacketOverhead( payload );
|
||||||
struct tr_bandwidth * b = io->bandwidth + TR_DOWN;
|
struct tr_bandwidth * b = io->bandwidth + TR_DOWN;
|
||||||
b->bytesLeft -= MIN( b->bytesLeft, (size_t)n );
|
b->bytesLeft -= MIN( b->bytesLeft, (size_t)n );
|
||||||
b->bytesUsed += n;
|
dbgmsg( io, "%zu new input bytes. bytesLeft is %zu", n, b->bytesLeft );
|
||||||
dbgmsg( io, "%zu new input bytes. bytesUsed is %zu, bytesLeft is %zu", n, b->bytesUsed, b->bytesLeft );
|
|
||||||
|
|
||||||
adjustInputBuffer( io );
|
adjustInputBuffer( io );
|
||||||
}
|
}
|
||||||
|
@ -615,15 +611,6 @@ tr_peerIoSupportsFEXT( const tr_peerIo * io )
|
||||||
***
|
***
|
||||||
**/
|
**/
|
||||||
|
|
||||||
size_t
|
|
||||||
tr_peerIoGetBandwidthUsed( const tr_peerIo * io,
|
|
||||||
tr_direction direction )
|
|
||||||
{
|
|
||||||
assert( io );
|
|
||||||
assert( direction == TR_UP || direction == TR_DOWN );
|
|
||||||
return io->bandwidth[direction].bytesUsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
tr_peerIoGetWriteBufferSpace( const tr_peerIo * io )
|
tr_peerIoGetWriteBufferSpace( const tr_peerIo * io )
|
||||||
{
|
{
|
||||||
|
@ -649,9 +636,9 @@ tr_peerIoGetWriteBufferSpace( const tr_peerIo * io )
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tr_peerIoSetBandwidth( tr_peerIo * io,
|
tr_peerIoAllocateBandwidth( tr_peerIo * io,
|
||||||
tr_direction direction,
|
tr_direction direction,
|
||||||
size_t bytesLeft )
|
size_t bytesLeft )
|
||||||
{
|
{
|
||||||
struct tr_bandwidth * b;
|
struct tr_bandwidth * b;
|
||||||
|
|
||||||
|
@ -660,7 +647,6 @@ tr_peerIoSetBandwidth( tr_peerIo * io,
|
||||||
|
|
||||||
b = io->bandwidth + direction;
|
b = io->bandwidth + direction;
|
||||||
b->isUnlimited = 0;
|
b->isUnlimited = 0;
|
||||||
b->bytesUsed = 0;
|
|
||||||
b->bytesLeft = bytesLeft;
|
b->bytesLeft = bytesLeft;
|
||||||
|
|
||||||
adjustOutputBuffer( io );
|
adjustOutputBuffer( io );
|
||||||
|
@ -678,7 +664,6 @@ tr_peerIoSetBandwidthUnlimited( tr_peerIo * io,
|
||||||
|
|
||||||
b = io->bandwidth + direction;
|
b = io->bandwidth + direction;
|
||||||
b->isUnlimited = 1;
|
b->isUnlimited = 1;
|
||||||
b->bytesUsed = 0;
|
|
||||||
b->bytesLeft = 0;
|
b->bytesLeft = 0;
|
||||||
|
|
||||||
adjustInputBuffer( io );
|
adjustInputBuffer( io );
|
||||||
|
@ -882,4 +867,3 @@ tr_peerIoGetAge( const tr_peerIo * io )
|
||||||
{
|
{
|
||||||
return time( NULL ) - io->timeCreated;
|
return time( NULL ) - io->timeCreated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,14 +198,11 @@ void tr_peerIoDrain( tr_peerIo * io,
|
||||||
***
|
***
|
||||||
**/
|
**/
|
||||||
|
|
||||||
size_t tr_peerIoGetBandwidthUsed( const tr_peerIo * io,
|
|
||||||
tr_direction direction );
|
|
||||||
|
|
||||||
size_t tr_peerIoGetWriteBufferSpace( const tr_peerIo * io );
|
size_t tr_peerIoGetWriteBufferSpace( const tr_peerIo * io );
|
||||||
|
|
||||||
void tr_peerIoSetBandwidth( tr_peerIo * io,
|
void tr_peerIoAllocateBandwidth( tr_peerIo * io,
|
||||||
tr_direction direction,
|
tr_direction direction,
|
||||||
size_t bytesLeft );
|
size_t bytesLeft );
|
||||||
|
|
||||||
void tr_peerIoSetBandwidthUnlimited( tr_peerIo * io,
|
void tr_peerIoSetBandwidthUnlimited( tr_peerIo * io,
|
||||||
tr_direction direction );
|
tr_direction direction );
|
||||||
|
|
|
@ -67,7 +67,7 @@ enum
|
||||||
|
|
||||||
/* number of unchoked peers per torrent.
|
/* number of unchoked peers per torrent.
|
||||||
* FIXME: this probably ought to be configurable */
|
* FIXME: this probably ought to be configurable */
|
||||||
MAX_UNCHOKED_PEERS = 12,
|
MAX_UNCHOKED_PEERS = 14,
|
||||||
|
|
||||||
/* number of bad pieces a peer is allowed to send before we ban them */
|
/* number of bad pieces a peer is allowed to send before we ban them */
|
||||||
MAX_BAD_PIECES_PER_PEER = 3,
|
MAX_BAD_PIECES_PER_PEER = 3,
|
||||||
|
@ -130,7 +130,6 @@ 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;
|
||||||
tr_ratecontrol * globalPoolRawSpeed[2];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define tordbg( t, ... ) \
|
#define tordbg( t, ... ) \
|
||||||
|
@ -520,8 +519,6 @@ tr_peerMgrNew( tr_session * session )
|
||||||
m->session = session;
|
m->session = session;
|
||||||
m->torrents = tr_ptrArrayNew( );
|
m->torrents = tr_ptrArrayNew( );
|
||||||
m->incomingHandshakes = tr_ptrArrayNew( );
|
m->incomingHandshakes = tr_ptrArrayNew( );
|
||||||
m->globalPoolRawSpeed[TR_CLIENT_TO_PEER] = tr_rcInit( );
|
|
||||||
m->globalPoolRawSpeed[TR_PEER_TO_CLIENT] = tr_rcInit( );
|
|
||||||
m->bandwidthTimer = tr_timerNew( session, bandwidthPulse, m, BANDWIDTH_PERIOD_MSEC );
|
m->bandwidthTimer = tr_timerNew( session, bandwidthPulse, m, BANDWIDTH_PERIOD_MSEC );
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
@ -532,8 +529,6 @@ tr_peerMgrFree( tr_peerMgr * manager )
|
||||||
managerLock( manager );
|
managerLock( manager );
|
||||||
|
|
||||||
tr_timerFree( &manager->bandwidthTimer );
|
tr_timerFree( &manager->bandwidthTimer );
|
||||||
tr_rcClose( manager->globalPoolRawSpeed[TR_CLIENT_TO_PEER] );
|
|
||||||
tr_rcClose( manager->globalPoolRawSpeed[TR_PEER_TO_CLIENT] );
|
|
||||||
|
|
||||||
/* free the handshakes. Abort invokes handshakeDoneCB(), which removes
|
/* free the handshakes. Abort invokes handshakeDoneCB(), which removes
|
||||||
* the item from manager->handshakes, so this is a little roundabout... */
|
* the item from manager->handshakes, so this is a little roundabout... */
|
||||||
|
@ -2362,17 +2357,29 @@ reconnectPulse( void * vtorrent )
|
||||||
*****
|
*****
|
||||||
****/
|
****/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#define DEBUG_DIRECTION TR_UP
|
||||||
|
#endif
|
||||||
|
|
||||||
static double
|
static double
|
||||||
allocateHowMuch( double desired_average_kb_per_sec,
|
bytesPerPulse( double KiB_per_second )
|
||||||
const tr_ratecontrol * ratecontrol )
|
{
|
||||||
|
return KiB_per_second * ( 1024.0 * BANDWIDTH_PERIOD_MSEC / 1000.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param currentSpeed current speed in KiB/s
|
||||||
|
* @param desiredSpeed desired speed in KiB/s
|
||||||
|
*/
|
||||||
|
static double
|
||||||
|
allocateHowMuch( tr_direction dir UNUSED, double currentSpeed, double desiredSpeed )
|
||||||
{
|
{
|
||||||
const int pulses_per_history = TR_RATECONTROL_HISTORY_MSEC / BANDWIDTH_PERIOD_MSEC;
|
const int pulses_per_history = TR_RATECONTROL_HISTORY_MSEC / BANDWIDTH_PERIOD_MSEC;
|
||||||
const double seconds_per_pulse = BANDWIDTH_PERIOD_MSEC / 1000.0;
|
const double current_bytes_per_pulse = bytesPerPulse( currentSpeed );
|
||||||
const double baseline_bytes_per_pulse = desired_average_kb_per_sec * 1024.0 * seconds_per_pulse;
|
const double desired_bytes_per_pulse = bytesPerPulse( desiredSpeed );
|
||||||
const double min = baseline_bytes_per_pulse * 0.80;
|
const double min = desired_bytes_per_pulse * 0.90;
|
||||||
const double max = baseline_bytes_per_pulse * 1.20;
|
const double max = desired_bytes_per_pulse * 1.25;
|
||||||
const double current_bytes_per_pulse = tr_rcRate( ratecontrol ) * 1024.0 * seconds_per_pulse;
|
const double next_pulse_bytes = desired_bytes_per_pulse * ( pulses_per_history + 1 )
|
||||||
const double next_pulse_bytes = baseline_bytes_per_pulse * ( pulses_per_history + 1 )
|
|
||||||
- ( current_bytes_per_pulse * pulses_per_history );
|
- ( current_bytes_per_pulse * pulses_per_history );
|
||||||
double clamped;
|
double clamped;
|
||||||
|
|
||||||
|
@ -2381,91 +2388,81 @@ allocateHowMuch( double desired_average_kb_per_sec,
|
||||||
clamped = MAX( clamped, min );
|
clamped = MAX( clamped, min );
|
||||||
clamped = MIN( clamped, max );
|
clamped = MIN( clamped, max );
|
||||||
|
|
||||||
#if 0
|
#ifdef DEBUG_DIRECTION
|
||||||
fprintf( stderr, "desiredAvgKB is %5.2f, rate is %5.2f, allocating %5.2f (%5.2f)\n",
|
if( dir == DEBUG_DIRECTION )
|
||||||
desired_average_kb_per_sec,
|
fprintf( stderr, "currentSpeed(%5.2f) desiredSpeed(%5.2f), allocating %5.2f (%5.2f)\n",
|
||||||
tr_rcRate( ratecontrol ),
|
currentSpeed,
|
||||||
|
desiredSpeed,
|
||||||
clamped/1024.0,
|
clamped/1024.0,
|
||||||
next_pulse_bytes/1024.0 );
|
next_pulse_bytes/1024.0 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return clamped;
|
return clamped;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Distributes 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 set
|
* @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 currentSpeed current speed in KiB/s for this set of peers
|
||||||
* @param desiredAvgKB overall bandwidth goal for this set of peers
|
* @param desiredSpeed desired speed in KiB/s 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 tr_ratecontrol * ratecontrol,
|
double currentSpeed,
|
||||||
double desiredAvgKB )
|
double desiredSpeed )
|
||||||
{
|
{
|
||||||
const int peerCount = tr_ptrArraySize( peerArray );
|
const int MINIMUM_WELFARE_BYTES = bytesPerPulse( 5 );
|
||||||
const double bytes = allocateHowMuch( desiredAvgKB, ratecontrol );
|
|
||||||
const double welfareBytes = MIN( 2048, bytes * 0.2 );
|
|
||||||
const double meritBytes = MAX( 0, bytes - welfareBytes );
|
|
||||||
tr_peer ** peers = (tr_peer**) tr_ptrArrayBase( peerArray );
|
|
||||||
int i;
|
int i;
|
||||||
double welfare;
|
double welfare;
|
||||||
size_t bytesUsed;
|
double meritBytes;
|
||||||
|
double meritMultiplier;
|
||||||
|
double welfareBytes;
|
||||||
|
const int peerCount = tr_ptrArraySize( peerArray );
|
||||||
|
const double bytes = allocateHowMuch( direction, currentSpeed, desiredSpeed );
|
||||||
|
tr_peer ** peers = (tr_peer**) tr_ptrArrayBase( peerArray );
|
||||||
|
|
||||||
assert( meritBytes >= 0.0 );
|
/* how many bytes we'll allocate based on merit.
|
||||||
assert( welfareBytes >= 0.0 );
|
*
|
||||||
assert( direction == TR_UP || direction == TR_DOWN );
|
* 1. When just getting started we want to give all the peers a lot
|
||||||
|
* of `welfare' allocation because we don't know which ones will
|
||||||
|
* turn out to be productive for us.
|
||||||
|
*
|
||||||
|
* 2. When we've reached steady state and are near our bandwidth limit,
|
||||||
|
* the bandwidth spent on `welfare' is going to come from peers that
|
||||||
|
* we already know are productive... which is probably a waste.
|
||||||
|
*
|
||||||
|
* 3. So we tie the merit/welfare allocations to the current speed.
|
||||||
|
* the closer the current speed gets to the maximum speed, the less
|
||||||
|
* welfare we allocate.
|
||||||
|
*
|
||||||
|
* 4. We always need to allocate /some/ welfare bytes, otherwise
|
||||||
|
* the other peers will starve.
|
||||||
|
*/
|
||||||
|
meritBytes = bytesPerPulse( MIN( currentSpeed * 1.2, desiredSpeed ) );
|
||||||
|
welfareBytes = bytes > meritBytes ? bytes - meritBytes : 0;
|
||||||
|
if( welfareBytes < MINIMUM_WELFARE_BYTES )
|
||||||
|
welfareBytes = MINIMUM_WELFARE_BYTES;
|
||||||
|
meritBytes = bytes - welfareBytes;
|
||||||
|
meritMultiplier = currentSpeed > 0.01 ? meritBytes / currentSpeed : 0.0;
|
||||||
|
|
||||||
for( i=bytesUsed=0; i<peerCount; ++i )
|
#ifdef DEBUG_DIRECTION
|
||||||
bytesUsed += tr_peerIoGetBandwidthUsed( peers[i]->io, direction );
|
if( direction == DEBUG_DIRECTION )
|
||||||
|
fprintf( stderr, "currentSpeed(%5.2f) desiredSpeed(%5.2f) - k[%.1f] merit [%.1f] welfare [%.1f]\n", currentSpeed, desiredSpeed, bytes/1024.0, meritBytes/1024.0, welfareBytes/1024.0 );
|
||||||
|
#endif
|
||||||
|
|
||||||
welfare = welfareBytes / peerCount;
|
/* how much welfare each peer gets */
|
||||||
|
welfare = welfareBytes / peerCount;
|
||||||
|
|
||||||
for( i=0; i<peerCount; ++i )
|
for( i=0; i<peerCount; ++i )
|
||||||
{
|
{
|
||||||
tr_peer * peer = peers[i];
|
tr_peer * peer = peers[i];
|
||||||
const double merit = bytesUsed
|
const size_t merit = tr_rcRate( peers[i]->pieceSpeed[direction] ) * meritMultiplier;
|
||||||
? ( meritBytes * tr_peerIoGetBandwidthUsed( peer->io, direction ) ) / bytesUsed
|
tr_peerIoAllocateBandwidth( peer->io, direction, merit + welfare );
|
||||||
: ( meritBytes / peerCount );
|
|
||||||
tr_peerIoSetBandwidth( peer->io, direction, merit + welfare );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
|
||||||
countHandshakeBandwidth( tr_ptrArray * handshakes,
|
|
||||||
tr_direction direction )
|
|
||||||
{
|
|
||||||
const int n = tr_ptrArraySize( handshakes );
|
|
||||||
int i;
|
|
||||||
size_t total;
|
|
||||||
|
|
||||||
for( i = total = 0; i < n; ++i )
|
|
||||||
{
|
|
||||||
tr_peerIo * io = tr_handshakeGetIO( tr_ptrArrayNth( handshakes, i ) );
|
|
||||||
total += tr_peerIoGetBandwidthUsed( io, direction );
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
countPeerBandwidth( tr_ptrArray * peers,
|
|
||||||
tr_direction direction )
|
|
||||||
{
|
|
||||||
const int n = tr_ptrArraySize( peers );
|
|
||||||
int i;
|
|
||||||
size_t total;
|
|
||||||
|
|
||||||
for( i = total = 0; i < n; ++i )
|
|
||||||
{
|
|
||||||
tr_peer * peer = tr_ptrArrayNth( peers, i );
|
|
||||||
total += tr_peerIoGetBandwidthUsed( peer->io, direction );
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
givePeersUnlimitedBandwidth( tr_ptrArray * peers,
|
givePeersUnlimitedBandwidth( tr_ptrArray * peers,
|
||||||
tr_direction direction )
|
tr_direction direction )
|
||||||
|
@ -2499,21 +2496,34 @@ pumpAllPeers( tr_peerMgr * mgr )
|
||||||
|
|
||||||
static void
|
static void
|
||||||
getBandwidthPeers( Torrent * t,
|
getBandwidthPeers( Torrent * t,
|
||||||
tr_direction direction,
|
tr_direction dir,
|
||||||
tr_ptrArray * appendme )
|
tr_ptrArray * appendme,
|
||||||
|
double * speed )
|
||||||
{
|
{
|
||||||
int i, peerCount;
|
int i, peerCount;
|
||||||
tr_peer ** peers;
|
tr_peer ** peers;
|
||||||
|
|
||||||
|
assert( t );
|
||||||
assert( torrentIsLocked( t ) );
|
assert( torrentIsLocked( t ) );
|
||||||
|
assert( dir == TR_UP || dir == TR_DOWN );
|
||||||
|
assert( appendme );
|
||||||
|
assert( speed );
|
||||||
|
|
||||||
peers = (tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
|
peers = (tr_peer **) tr_ptrArrayPeek( t->peers, &peerCount );
|
||||||
|
|
||||||
for( i=0; i<peerCount; ++i )
|
for( i=0; i<peerCount; ++i )
|
||||||
if( peers[i]->msgs )
|
{
|
||||||
if( ( ( direction == TR_PEER_TO_CLIENT ) && clientIsDownloadingFrom( peers[i] ) )
|
tr_peer * p = peers[i];
|
||||||
|| ( ( direction == TR_CLIENT_TO_PEER ) && clientIsUploadingTo( peers[i] ) ) )
|
|
||||||
tr_ptrArrayAppend( appendme, peers[i] );
|
if( p->msgs )
|
||||||
|
{
|
||||||
|
if( ( ( dir == TR_DOWN ) && clientIsDownloadingFrom( p ) ) || ( ( dir == TR_UP ) && clientIsUploadingTo( p ) ) )
|
||||||
|
{
|
||||||
|
tr_ptrArrayAppend( appendme, p );
|
||||||
|
*speed += tr_rcRate( p->pieceSpeed[dir] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2523,7 +2533,7 @@ getBandwidthPeers( Torrent * t,
|
||||||
* @param direction whether to allocate upload or download bandwidth
|
* @param direction whether to allocate upload or download bandwidth
|
||||||
* @return the amount of directional bandwidth used since the last pulse.
|
* @return the amount of directional bandwidth used since the last pulse.
|
||||||
*/
|
*/
|
||||||
static double
|
static void
|
||||||
allocateBandwidth( tr_peerMgr * mgr,
|
allocateBandwidth( tr_peerMgr * mgr,
|
||||||
tr_direction direction )
|
tr_direction direction )
|
||||||
{
|
{
|
||||||
|
@ -2531,8 +2541,7 @@ allocateBandwidth( tr_peerMgr * mgr,
|
||||||
const int torrentCount = tr_ptrArraySize( mgr->torrents );
|
const int torrentCount = tr_ptrArraySize( mgr->torrents );
|
||||||
Torrent ** torrents = (Torrent **) tr_ptrArrayBase( mgr->torrents );
|
Torrent ** torrents = (Torrent **) tr_ptrArrayBase( mgr->torrents );
|
||||||
tr_ptrArray * globalPool = tr_ptrArrayNew( );
|
tr_ptrArray * globalPool = tr_ptrArrayNew( );
|
||||||
double allBytesUsed = 0;
|
double globalPoolSpeed = 0;
|
||||||
size_t poolBytesUsed = 0;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
assert( mgr );
|
assert( mgr );
|
||||||
|
@ -2544,22 +2553,12 @@ allocateBandwidth( tr_peerMgr * mgr,
|
||||||
for( i=0; i<torrentCount; ++i )
|
for( i=0; i<torrentCount; ++i )
|
||||||
{
|
{
|
||||||
Torrent * t = torrents[i];
|
Torrent * t = torrents[i];
|
||||||
size_t used;
|
|
||||||
tr_speedlimit speedMode;
|
tr_speedlimit speedMode;
|
||||||
|
|
||||||
/* no point in allocating bandwidth for stopped torrents */
|
/* no point in allocating bandwidth for stopped torrents */
|
||||||
if( tr_torrentGetActivity( t->tor ) == TR_STATUS_STOPPED )
|
if( tr_torrentGetActivity( t->tor ) == TR_STATUS_STOPPED )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
used = countPeerBandwidth( t->peers, direction );
|
|
||||||
countHandshakeBandwidth( t->outgoingHandshakes, direction );
|
|
||||||
|
|
||||||
/* remember this torrent's bytes used */
|
|
||||||
tr_rcTransferred( t->tor->rawSpeed[direction], used );
|
|
||||||
|
|
||||||
/* add this torrent's bandwidth use to allBytesUsed */
|
|
||||||
allBytesUsed += used;
|
|
||||||
|
|
||||||
/* if piece data is disallowed, don't bother limiting bandwidth --
|
/* if piece data is disallowed, don't bother limiting bandwidth --
|
||||||
* we won't be asking for, or sending out, any pieces */
|
* we won't be asking for, or sending out, any pieces */
|
||||||
if( !tr_torrentIsPieceTransferAllowed( t->tor, direction ) )
|
if( !tr_torrentIsPieceTransferAllowed( t->tor, direction ) )
|
||||||
|
@ -2574,37 +2573,26 @@ allocateBandwidth( tr_peerMgr * mgr,
|
||||||
givePeersUnlimitedBandwidth( t->peers, direction );
|
givePeersUnlimitedBandwidth( t->peers, direction );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TR_SPEEDLIMIT_SINGLE:
|
case TR_SPEEDLIMIT_SINGLE: {
|
||||||
{
|
|
||||||
tr_ptrArray * peers = tr_ptrArrayNew( );
|
tr_ptrArray * peers = tr_ptrArrayNew( );
|
||||||
getBandwidthPeers( t, direction, peers );
|
double speed = 0;
|
||||||
setPeerBandwidth( peers, direction,
|
getBandwidthPeers( t, direction, peers, &speed );
|
||||||
t->tor->rawSpeed[direction],
|
setPeerBandwidth( peers, direction, speed, tr_torrentGetSpeedLimit( t->tor, direction ) );
|
||||||
tr_torrentGetSpeedLimit( t->tor, direction ) );
|
|
||||||
tr_ptrArrayFree( peers, NULL );
|
tr_ptrArrayFree( peers, NULL );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TR_SPEEDLIMIT_GLOBAL:
|
case TR_SPEEDLIMIT_GLOBAL:
|
||||||
getBandwidthPeers( t, direction, globalPool );
|
getBandwidthPeers( t, direction, globalPool, &globalPoolSpeed );
|
||||||
poolBytesUsed += used;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add incoming handshakes to the global pool */
|
|
||||||
i = countHandshakeBandwidth( mgr->incomingHandshakes, direction );
|
|
||||||
allBytesUsed += i;
|
|
||||||
poolBytesUsed += i;
|
|
||||||
|
|
||||||
tr_rcTransferred( mgr->globalPoolRawSpeed[direction], poolBytesUsed );
|
|
||||||
|
|
||||||
/* handle the global pool's connections */
|
/* handle the global pool's connections */
|
||||||
if( !tr_sessionIsSpeedLimitEnabled( session, direction ) )
|
if( !tr_sessionIsSpeedLimitEnabled( session, direction ) )
|
||||||
givePeersUnlimitedBandwidth( globalPool, direction );
|
givePeersUnlimitedBandwidth( globalPool, direction );
|
||||||
else
|
else
|
||||||
setPeerBandwidth( globalPool, direction,
|
setPeerBandwidth( globalPool, direction, globalPoolSpeed,
|
||||||
mgr->globalPoolRawSpeed[direction],
|
|
||||||
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 */
|
||||||
|
@ -2612,7 +2600,6 @@ allocateBandwidth( tr_peerMgr * mgr,
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
tr_ptrArrayFree( globalPool, NULL );
|
tr_ptrArrayFree( globalPool, NULL );
|
||||||
return allBytesUsed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
Loading…
Reference in a new issue