From 42fe27c067c58bbd31ed67a80bb401ec98744280 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 8 Nov 2008 02:49:04 +0000 Subject: [PATCH] more fucking around with the speed measurements. --- cli/cli.c | 6 +- gtk/torrent-cell-renderer.c | 4 +- gtk/tr-core.c | 16 ++--- gtk/tr-window.c | 20 ++++--- libtransmission/peer-io.c | 3 + libtransmission/peer-mgr.c | 104 ++++++++++++++++----------------- libtransmission/ratecontrol.c | 11 +++- libtransmission/ratecontrol.h | 5 ++ libtransmission/rpcimpl.c | 10 ++-- libtransmission/session.c | 24 +++++--- libtransmission/session.h | 12 +--- libtransmission/torrent.c | 25 ++++---- libtransmission/torrent.h | 9 +-- libtransmission/transmission.h | 30 +++++++--- macosx/Badger.m | 9 ++- macosx/Controller.m | 4 +- macosx/Torrent.m | 4 +- 17 files changed, 159 insertions(+), 137 deletions(-) diff --git a/cli/cli.c b/cli/cli.c index 835505be8..b240adee8 100644 --- a/cli/cli.c +++ b/cli/cli.c @@ -282,9 +282,9 @@ getStatusStr( const tr_stat * st, st->percentDone * 100.0, st->peersSendingToUs, st->peersConnected, - st->rateDownload, + st->pieceDownloadSpeed, st->peersGettingFromUs, - st->rateUpload, + st->pieceUploadSpeed, ratioStr ); } else if( st->activity & TR_STATUS_SEED ) @@ -295,7 +295,7 @@ getStatusStr( const tr_stat * st, buf, buflen, "Seeding, uploading to %d of %d peer(s), %.0f KB/s [%s]", st->peersGettingFromUs, st->peersConnected, - st->rateUpload, ratioStr ); + st->pieceUploadSpeed, ratioStr ); } else *buf = '\0'; } diff --git a/gtk/torrent-cell-renderer.c b/gtk/torrent-cell-renderer.c index ac7e7e59a..4b654e816 100644 --- a/gtk/torrent-cell-renderer.c +++ b/gtk/torrent-cell-renderer.c @@ -108,9 +108,9 @@ getShortTransferString( const tr_stat * torStat, const int haveUp = torStat->peersGettingFromUs > 0; if( haveDown ) - tr_strlspeed( downStr, torStat->rateDownload, sizeof( downStr ) ); + tr_strlspeed( downStr, torStat->pieceDownloadSpeed, sizeof( downStr ) ); if( haveUp ) - tr_strlspeed( upStr, torStat->rateUpload, sizeof( upStr ) ); + tr_strlspeed( upStr, torStat->pieceUploadSpeed, sizeof( upStr ) ); if( haveDown && haveUp ) /* Translators: do not translate the "speed|" disambiguation prefix. diff --git a/gtk/tr-core.c b/gtk/tr-core.c index 54990c97f..1ea901332 100644 --- a/gtk/tr-core.c +++ b/gtk/tr-core.c @@ -308,8 +308,8 @@ compareByActivity( GtkTreeModel * model, sa = tr_torrentStatCached( ta ); sb = tr_torrentStatCached( tb ); - if( ( i = compareDouble( sa->rateUpload + sa->rateDownload, - sb->rateUpload + sb->rateDownload ) ) ) + if( ( i = compareDouble( sa->pieceUploadSpeed + sa->pieceDownloadSpeed, + sb->pieceUploadSpeed + sb->pieceDownloadSpeed ) ) ) return i; if( sa->uploadedEver != sb->uploadedEver ) @@ -745,13 +745,13 @@ tr_core_get_stats( const TrCore * core, if( !isDisposed( core ) ) { - tr_sessionGetSpeed( core->priv->session, - &setme->clientDownloadSpeed, - &setme->clientUploadSpeed ); + tr_session * session = core->priv->session; - gtk_tree_model_foreach( core->priv->model, - statsForeach, - setme ); + setme->clientDownloadSpeed = tr_sessionGetPieceSpeed( session, TR_DOWN ); + + setme->clientUploadSpeed = tr_sessionGetPieceSpeed( session, TR_UP ); + + gtk_tree_model_foreach( core->priv->model, statsForeach, setme ); } } diff --git a/gtk/tr-window.c b/gtk/tr-window.c index cae952d3b..cd68a899f 100644 --- a/gtk/tr-window.c +++ b/gtk/tr-window.c @@ -769,15 +769,21 @@ updateStats( PrivateData * p ) static void updateSpeeds( PrivateData * p ) { - char buf[128]; - float u, d; tr_session * session = tr_core_session( p->core ); - tr_sessionGetSpeed( session, &d, &u ); - tr_strlspeed( buf, d, sizeof( buf ) ); - gtk_label_set_text( GTK_LABEL( p->dl_lb ), buf ); - tr_strlspeed( buf, u, sizeof( buf ) ); - gtk_label_set_text( GTK_LABEL( p->ul_lb ), buf ); + if( session != NULL ) + { + char buf[128]; + double d; + + d = tr_sessionGetPieceSpeed( session, TR_DOWN ); + tr_strlspeed( buf, d, sizeof( buf ) ); + gtk_label_set_text( GTK_LABEL( p->dl_lb ), buf ); + + d = tr_sessionGetPieceSpeed( session, TR_UP ); + tr_strlspeed( buf, d, sizeof( buf ) ); + gtk_label_set_text( GTK_LABEL( p->ul_lb ), buf ); + } } void diff --git a/libtransmission/peer-io.c b/libtransmission/peer-io.c index ffedeaca1..d495ff502 100644 --- a/libtransmission/peer-io.c +++ b/libtransmission/peer-io.c @@ -29,6 +29,7 @@ #include "crypto.h" #include "net.h" #include "peer-io.h" +#include "ratecontrol.h" #include "trevent.h" #include "utils.h" @@ -203,6 +204,7 @@ didWriteWrapper( struct bufferevent * e, struct tr_bandwidth * b = &io->bandwidth[TR_UP]; b->bytesLeft -= MIN( b->bytesLeft, (size_t)n ); b->bytesUsed += n; + tr_rcTransferred( io->session->rawSpeed[TR_UP], n ); dbgmsg( io, "wrote %zu bytes to peer... upload bytesLeft is now %zu", n, @@ -235,6 +237,7 @@ canReadWrapper( struct bufferevent * e, struct tr_bandwidth * b = io->bandwidth + TR_DOWN; b->bytesLeft -= MIN( b->bytesLeft, (size_t)n ); b->bytesUsed += n; + tr_rcTransferred( io->session->rawSpeed[TR_DOWN], n ); dbgmsg( io, "%zu new input bytes. bytesUsed is %zu, bytesLeft is %zu", n, b->bytesUsed, diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index 6571207b4..00c754988 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -54,6 +54,9 @@ enum /* how frequently to decide which peers live and die */ RECONNECT_PERIOD_MSEC = ( 2 * 1000 ), + + /* how frequently to reallocate bandwidth */ + BANDWIDTH_PERIOD_MSEC = 250, /* max # of peers to ask fer per torrent per reconnect pulse */ MAX_RECONNECTIONS_PER_PULSE = 2, @@ -123,12 +126,11 @@ Torrent; struct tr_peerMgr { - uint8_t bandwidthPulseNumber; - tr_session * session; - tr_ptrArray * torrents; /* Torrent */ - tr_ptrArray * incomingHandshakes; /* tr_handshake */ - tr_timer * bandwidthTimer; - double globalPoolHistory[2][BANDWIDTH_PULSE_HISTORY]; + tr_session * session; + tr_ptrArray * torrents; /* Torrent */ + tr_ptrArray * incomingHandshakes; /* tr_handshake */ + tr_timer * bandwidthTimer; + tr_ratecontrol * globalPoolRawSpeed[2]; }; #define tordbg( t, ... ) \ @@ -505,6 +507,7 @@ tr_peerMgrGenerateAllowedSet( static int bandwidthPulse( void * vmgr ); + tr_peerMgr* tr_peerMgrNew( tr_session * session ) { @@ -513,9 +516,9 @@ tr_peerMgrNew( tr_session * session ) m->session = session; m->torrents = tr_ptrArrayNew( ); m->incomingHandshakes = tr_ptrArrayNew( ); - m->bandwidthPulseNumber = -1; - m->bandwidthTimer = tr_timerNew( session, bandwidthPulse, - m, 1000 / BANDWIDTH_PULSES_PER_SECOND ); + 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 ); return m; } @@ -525,6 +528,8 @@ tr_peerMgrFree( tr_peerMgr * manager ) managerLock( manager ); 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 * the item from manager->handshakes, so this is a little roundabout... */ @@ -2326,34 +2331,30 @@ reconnectPulse( void * vtorrent ) ****/ static double -allocateHowMuch( double desiredAvgKB, - const double * history ) -{ - const double baseline = desiredAvgKB * 1024.0 / - BANDWIDTH_PULSES_PER_SECOND; - const double min = baseline * 0.85; - const double max = baseline * 1.15; - int i; - double usedBytes; - double n; - double clamped; - - for( usedBytes = i = 0; i < BANDWIDTH_PULSE_HISTORY; ++i ) - usedBytes += history[i]; - - n = ( desiredAvgKB * 1024.0 ) - * ( BANDWIDTH_PULSE_HISTORY + 1.0 ) - / BANDWIDTH_PULSES_PER_SECOND - - usedBytes; +allocateHowMuch( double desired_average_kb_per_sec, + const tr_ratecontrol * ratecontrol ) +{ + const int pulses_per_history = TR_RATECONTROL_HISTORY_MSEC / BANDWIDTH_PERIOD_MSEC; + const double seconds_per_pulse = BANDWIDTH_PERIOD_MSEC / 1000.0; + const double baseline_bytes_per_pulse = desired_average_kb_per_sec * 1024.0 * seconds_per_pulse; + const double min = baseline_bytes_per_pulse * 0.85; + const double max = baseline_bytes_per_pulse * 1.15; + const double current_bytes_per_pulse = tr_rcRate( ratecontrol ) * 1024.0 * seconds_per_pulse; + const double next_pulse_bytes = baseline_bytes_per_pulse * ( pulses_per_history + 1 ) + - ( current_bytes_per_pulse * pulses_per_history ); + double clamped; /* clamp the return value to lessen oscillation */ - clamped = n; + clamped = next_pulse_bytes; 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 );*/ + +fprintf( stderr, "desiredAvgKB is %.2f, rate is %.2f, allocating %.2f (%.2f)\n", + desired_average_kb_per_sec, + tr_rcRate( ratecontrol ), + clamped/1024.0, + next_pulse_bytes/1024.0 ); + return clamped; } @@ -2366,13 +2367,13 @@ allocateHowMuch( double desiredAvgKB, * @param desiredAvgKB overall bandwidth goal for this set of peers */ static void -setPeerBandwidth( tr_ptrArray * peerArray, - const tr_direction direction, - const double * history, - double desiredAvgKB ) +setPeerBandwidth( tr_ptrArray * peerArray, + const tr_direction direction, + const tr_ratecontrol * ratecontrol, + double desiredAvgKB ) { const int peerCount = tr_ptrArraySize( peerArray ); - const double bytes = allocateHowMuch( desiredAvgKB, history ); + 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 ); @@ -2489,7 +2490,6 @@ allocateBandwidth( tr_peerMgr * mgr, tr_direction direction ) { tr_session * session = mgr->session; - const int pulseNumber = mgr->bandwidthPulseNumber; const int torrentCount = tr_ptrArraySize( mgr->torrents ); Torrent ** torrents = (Torrent **) tr_ptrArrayBase( mgr->torrents ); tr_ptrArray * globalPool = tr_ptrArrayNew( ); @@ -2503,16 +2503,21 @@ allocateBandwidth( tr_peerMgr * mgr, /* before allocating bandwidth, pump the connected peers */ pumpAllPeers( mgr ); - for( i = 0; i < torrentCount; ++i ) + for( i=0; ipeers, direction ); + size_t used; tr_speedlimit speedMode; + /* no point in allocating bandwidth for stopped torrents */ + if( tr_torrentGetActivity( t->tor ) == TR_STATUS_STOPPED ) + continue; + + used = countPeerBandwidth( t->peers, direction ); countHandshakeBandwidth( t->outgoingHandshakes, direction ); /* remember this torrent's bytes used */ - t->tor->rateHistory[direction][pulseNumber] = used; + tr_rcTransferred( t->tor->rawSpeed[direction], used ); /* add this torrent's bandwidth use to allBytesUsed */ allBytesUsed += used; @@ -2533,9 +2538,8 @@ allocateBandwidth( tr_peerMgr * mgr, case TR_SPEEDLIMIT_SINGLE: setPeerBandwidth( t->peers, direction, - t->tor->rateHistory[direction], - tr_torrentGetSpeedLimit( t->tor, - direction ) ); + t->tor->rawSpeed[direction], + tr_torrentGetSpeedLimit( t->tor, direction ) ); break; case TR_SPEEDLIMIT_GLOBAL: @@ -2556,15 +2560,15 @@ allocateBandwidth( tr_peerMgr * mgr, allBytesUsed += i; poolBytesUsed += i; - mgr->globalPoolHistory[direction][pulseNumber] = poolBytesUsed; + tr_rcTransferred( mgr->globalPoolRawSpeed[direction], poolBytesUsed ); /* handle the global pool's connections */ if( !tr_sessionIsSpeedLimitEnabled( session, direction ) ) givePeersUnlimitedBandwidth( globalPool, direction ); else setPeerBandwidth( globalPool, direction, - mgr->globalPoolHistory[direction], - tr_sessionGetSpeedLimit( session, direction ) ); + mgr->globalPoolRawSpeed[direction], + tr_sessionGetSpeedLimit( session, direction ) ); /* now that we've allocated bandwidth, pump all the connected peers */ pumpAllPeers( mgr ); @@ -2582,10 +2586,6 @@ bandwidthPulse( void * vmgr ) managerLock( mgr ); - /* keep track of how far we are into the cycle */ - if( ++mgr->bandwidthPulseNumber == BANDWIDTH_PULSE_HISTORY ) - mgr->bandwidthPulseNumber = 0; - /* allocate the upload and download bandwidth */ for( i = 0; i < 2; ++i ) allocateBandwidth( mgr, i ); diff --git a/libtransmission/ratecontrol.c b/libtransmission/ratecontrol.c index 6c72ab484..c94f3511c 100644 --- a/libtransmission/ratecontrol.c +++ b/libtransmission/ratecontrol.c @@ -29,9 +29,14 @@ #include "ratecontrol.h" #include "utils.h" -#define INTERVAL_MSEC 1000 -#define GRANULARITY_MSEC 200 -#define HISTORY_SIZE ( INTERVAL_MSEC / GRANULARITY_MSEC ) +enum +{ + INTERVAL_MSEC = TR_RATECONTROL_HISTORY_MSEC, + + GRANULARITY_MSEC = 250, + + HISTORY_SIZE = ( INTERVAL_MSEC / GRANULARITY_MSEC ) +}; struct tr_transfer { diff --git a/libtransmission/ratecontrol.h b/libtransmission/ratecontrol.h index 3f6a2b47d..32d690c2c 100644 --- a/libtransmission/ratecontrol.h +++ b/libtransmission/ratecontrol.h @@ -25,6 +25,11 @@ #ifndef _TR_RATECONTROL_H_ #define _TR_RATECONTROL_H_ +enum +{ + TR_RATECONTROL_HISTORY_MSEC = 2000 +}; + typedef struct tr_ratecontrol tr_ratecontrol; diff --git a/libtransmission/rpcimpl.c b/libtransmission/rpcimpl.c index 79e1acdfa..28a1039c6 100644 --- a/libtransmission/rpcimpl.c +++ b/libtransmission/rpcimpl.c @@ -361,9 +361,9 @@ addField( const tr_torrent * tor, tr_bencListAddInt( p, inf->files[i].priority ); } else if( !strcmp( key, "rateDownload" ) ) - tr_bencDictAddInt( d, key, (int)( st->rateDownload * 1024 ) ); + tr_bencDictAddInt( d, key, (int)( st->pieceDownloadSpeed * 1024 ) ); else if( !strcmp( key, "rateUpload" ) ) - tr_bencDictAddInt( d, key, (int)( st->rateUpload * 1024 ) ); + tr_bencDictAddInt( d, key, (int)( st->pieceUploadSpeed * 1024 ) ); else if( !strcmp( key, "recheckProgress" ) ) tr_bencDictAddDouble( d, key, st->recheckProgress ); else if( !strcmp( key, "scrapeResponse" ) ) @@ -682,11 +682,9 @@ sessionStats( tr_handle * h, { tr_benc * d = tr_bencDictAddDict( args_out, "session-stats", 10 ); tr_torrent * tor = NULL; - float up, down; int running = 0; int total = 0; - tr_sessionGetSpeed( h, &down, &up ); while( ( tor = tr_torrentNext( h, tor ) ) ) { ++total; @@ -695,10 +693,10 @@ sessionStats( tr_handle * h, } tr_bencDictAddInt( d, "activeTorrentCount", running ); - tr_bencDictAddInt( d, "downloadSpeed", (int)( down * 1024 ) ); + tr_bencDictAddInt( d, "downloadSpeed", (int)( tr_sessionGetPieceSpeed( h, TR_DOWN ) * 1024 ) ); tr_bencDictAddInt( d, "pausedTorrentCount", total - running ); tr_bencDictAddInt( d, "torrentCount", total ); - tr_bencDictAddInt( d, "uploadSpeed", (int)( up * 1024 ) ); + tr_bencDictAddInt( d, "uploadSpeed", (int)( tr_sessionGetPieceSpeed( h, TR_UP ) * 1024 ) ); return NULL; } diff --git a/libtransmission/session.c b/libtransmission/session.c index 51b35def4..1a1439ff1 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -256,6 +256,8 @@ tr_sessionInitFull( const char * configDir, h->proxyPassword = tr_strdup( proxyPassword ); h->pieceSpeed[TR_PEER_TO_CLIENT] = tr_rcInit( ); h->pieceSpeed[TR_CLIENT_TO_PEER] = tr_rcInit( ); + h->rawSpeed[TR_PEER_TO_CLIENT] = tr_rcInit( ); + h->rawSpeed[TR_CLIENT_TO_PEER] = tr_rcInit( ); if( configDir == NULL ) configDir = tr_getDefaultConfigDir( ); @@ -500,16 +502,20 @@ tr_sessionGetPeerLimit( const tr_handle * handle UNUSED ) **** ***/ -void -tr_sessionGetSpeed( const tr_handle * session, - float * toClient, - float * toPeer ) +double +tr_sessionGetPieceSpeed( const tr_session * session, tr_direction dir ) +{ + assert( dir==TR_UP || dir==TR_DOWN ); + + return session ? tr_rcRate( session->pieceSpeed[dir] ) : 0.0; +} + +double +tr_sessionGetRawSpeed( const tr_session * session, tr_direction dir ) { - if( session && toClient ) - *toClient = tr_rcRate( session->pieceSpeed[TR_PEER_TO_CLIENT] ); + assert( dir==TR_UP || dir==TR_DOWN ); - if( session && toPeer ) - *toPeer = tr_rcRate( session->pieceSpeed[TR_CLIENT_TO_PEER] ); + return session ? tr_rcRate( session->rawSpeed[dir] ) : 0.0; } int @@ -625,6 +631,8 @@ tr_sessionClose( tr_handle * session ) /* free the session memory */ tr_rcClose( session->pieceSpeed[TR_PEER_TO_CLIENT] ); tr_rcClose( session->pieceSpeed[TR_CLIENT_TO_PEER] ); + tr_rcClose( session->rawSpeed[TR_PEER_TO_CLIENT] ); + tr_rcClose( session->rawSpeed[TR_CLIENT_TO_PEER] ); tr_lockFree( session->lock ); for( i = 0; i < session->metainfoLookupCount; ++i ) tr_free( session->metainfoLookup[i].filename ); diff --git a/libtransmission/session.h b/libtransmission/session.h index 969811b8f..e447c4236 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -35,15 +35,6 @@ #endif #endif -enum -{ - /* How frequently to reallocate peer bandwidth. */ - BANDWIDTH_PULSES_PER_SECOND = 4, - - /* 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; @@ -117,6 +108,9 @@ struct tr_handle /* the rate at which pieces are being transferred between client and peer. * protocol overhead is NOT included; this is only the piece data */ struct tr_ratecontrol * pieceSpeed[2]; + + /* the rate at which bytes are being transferred between client and peer. */ + struct tr_ratecontrol * rawSpeed[2]; }; const char * tr_sessionFindTorrentFile( const tr_session * session, diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index bbb9abf72..24fcda868 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -496,6 +496,8 @@ torrentRealInit( tr_handle * h, randomizeTiers( info ); + tor->rawSpeed[TR_CLIENT_TO_PEER] = tr_rcInit( ); + tor->rawSpeed[TR_PEER_TO_CLIENT] = tr_rcInit( ); tor->pieceSpeed[TR_CLIENT_TO_PEER] = tr_rcInit( ); tor->pieceSpeed[TR_PEER_TO_CLIENT] = tr_rcInit( ); @@ -746,16 +748,6 @@ tr_torrentInfo( const tr_torrent * tor ) return tor ? &tor->info : NULL; } -static double -tr_torrentGetRate( const tr_torrent * tor, - tr_direction direction ) -{ - assert( tor != NULL ); - assert( direction == TR_UP || direction == TR_DOWN ); - - return tr_rcRate( tor->pieceSpeed[direction] ); -} - const tr_stat * tr_torrentStatCached( tr_torrent * tor ) { @@ -822,9 +814,10 @@ tr_torrentStat( tr_torrent * tor ) &s->peersGettingFromUs, s->peersFrom ); - s->rateDownload = tr_torrentGetRate( tor, TR_PEER_TO_CLIENT ); - - s->rateUpload = tr_torrentGetRate( tor, TR_CLIENT_TO_PEER ); + s->rawUploadSpeed = tr_rcRate( tor->rawSpeed[TR_UP] ); + s->rawDownloadSpeed = tr_rcRate( tor->rawSpeed[TR_DOWN] ); + s->pieceUploadSpeed = tr_rcRate( tor->pieceSpeed[TR_UP] ); + s->pieceDownloadSpeed = tr_rcRate( tor->pieceSpeed[TR_DOWN] ); usableSeeds += tor->info.webseedCount; @@ -880,10 +873,10 @@ tr_torrentStat( tr_torrent * tor ) if( s->leftUntilDone > s->desiredAvailable ) s->eta = TR_ETA_NOT_AVAIL; - else if( s->rateDownload < 0.1 ) + else if( s->pieceDownloadSpeed < 0.1 ) s->eta = TR_ETA_UNKNOWN; else - s->eta = s->leftUntilDone / s->rateDownload / 1024.0; + s->eta = s->leftUntilDone / s->pieceDownloadSpeed / 1024.0; s->ratio = tr_getRatio( s->uploadedEver, @@ -1109,6 +1102,8 @@ freeTorrent( tr_torrent * tor ) tr_rcClose( tor->pieceSpeed[TR_PEER_TO_CLIENT] ); tr_rcClose( tor->pieceSpeed[TR_CLIENT_TO_PEER] ); + tr_rcClose( tor->rawSpeed[TR_PEER_TO_CLIENT] ); + tr_rcClose( tor->rawSpeed[TR_CLIENT_TO_PEER] ); tr_metainfoFree( inf ); tr_free( tor ); diff --git a/libtransmission/torrent.h b/libtransmission/torrent.h index c06d8264a..166431ed0 100644 --- a/libtransmission/torrent.h +++ b/libtransmission/torrent.h @@ -229,15 +229,12 @@ struct tr_torrent int uniqueId; - /* this is the count of raw bytes transferred between the - * client and its peers over the past HISTORY time slices. - * this count is used for bandwidth allocation, and includes - * piece data, protocol overhead, and estimated tcp header overhead. */ - double rateHistory[2][BANDWIDTH_PULSE_HISTORY]; - /* the rate at which pieces are being transferred between client and * its peers. protocol overhead is NOT included; only the piece data */ struct tr_ratecontrol * pieceSpeed[2]; + + /* the rate at which bytes are being sent between client and peers */ + struct tr_ratecontrol * rawSpeed[2]; }; #endif diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index c88b2e86d..aacbf57c8 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -559,9 +559,11 @@ void tr_sessionSetSpeedLimitEnabled( tr_session * session, tr_direction direction, int isEnabled ); -void tr_sessionGetSpeed( const tr_session * session, - float * overall_down_KiBs, - float * overall_up_KiBs ); +double tr_sessionGetRawSpeed( const tr_session * session, + tr_direction direection ); + +double tr_sessionGetPieceSpeed( const tr_session * session, + tr_direction direection ); int tr_sessionIsSpeedLimitEnabled( const tr_session * session, tr_direction direction ); @@ -1184,6 +1186,8 @@ typedef enum } tr_torrent_activity; +tr_torrent_activity tr_torrentGetActivity( tr_torrent * ); + #define TR_STATUS_IS_ACTIVE( s ) ( ( s ) != TR_STATUS_STOPPED ) typedef enum @@ -1194,8 +1198,6 @@ typedef enum } tr_lockfile_state_t; -tr_torrent_activity tr_torrentGetActivity( tr_torrent * ); - enum { TR_PEER_FROM_INCOMING = 0, /* connections made to the listening port */ @@ -1256,11 +1258,21 @@ typedef struct tr_stat @see tr_stat.leftUntilDone */ float percentDone; - /** Download speed in KiB/s */ - double rateDownload; + /** Speed all data being sent for this torrent. (KiB/s) + This includes piece data, protocol messages, and TCP overhead */ + double rawUploadSpeed; + + /** Speed all data being received for this torrent. (KiB/s) + This includes piece data, protocol messages, and TCP overhead */ + double rawDownloadSpeed; + + /** Speed all piece being sent for this torrent. (KiB/s) + This ONLY counts piece data. */ + double pieceUploadSpeed; - /** Upload speed in KiB/s */ - double rateUpload; + /** Speed all piece being received for this torrent. (KiB/s) + This ONLY counts piece data. */ + double pieceDownloadSpeed; #define TR_ETA_NOT_AVAIL -1 #define TR_ETA_UNKNOWN -2 diff --git a/macosx/Badger.m b/macosx/Badger.m index 433b5d06b..6c38fbd1b 100644 --- a/macosx/Badger.m +++ b/macosx/Badger.m @@ -85,11 +85,10 @@ { if ([NSApp isOnLeopardOrBetter]) { - float downloadRate = 0.0, uploadRate = 0.0; BOOL badgeDownload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeDownloadRate"], badgeUpload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeUploadRate"]; - if (badgeDownload || badgeUpload) - tr_sessionGetSpeed(fLib, badgeDownload ? &downloadRate : NULL, badgeUpload ? &uploadRate : NULL); + float downloadRate = badgeDownload ? tr_sessionGetPieceSpeed( fLib, TR_DOWN ) : 0.0f; + float uploadRate = badgeUpload ? tr_sessionGetPieceSpeed( fLib, TR_UP ) : 0.0f; //only update if the badged values change if ([(BadgeView *)[[NSApp dockTile] contentView] setRatesWithDownload: downloadRate upload: uploadRate]) @@ -152,8 +151,8 @@ //set upload and download rate badges NSString * downloadRateString = nil, * uploadRateString = nil; - float downloadRate, uploadRate; - tr_sessionGetSpeed(fLib, &downloadRate, &uploadRate); + float downloadRate = tr_sessionGetPieceSpeed( fLib, TR_DOWN ); + float uploadRate = tr_sessionGetPieceSpeed( fLib, TR_UP ); if (checkDownload && downloadRate >= 0.1) downloadRateString = [NSString stringForSpeedAbbrev: downloadRate]; diff --git a/macosx/Controller.m b/macosx/Controller.m index 126d7dc51..71ebc9bb7 100644 --- a/macosx/Controller.m +++ b/macosx/Controller.m @@ -1507,8 +1507,8 @@ static void sleepCallback(void * controller, io_service_t y, natural_t messageTy if (![fStatusBar isHidden]) { //set rates - float downloadRate, uploadRate; - tr_sessionGetSpeed(fLib, &downloadRate, &uploadRate); + float downloadRate = tr_sessionGetPieceSpeed( fLib, TR_DOWN ); + float uploadRate = tr_sessionGetPieceSpeed( fLib, TR_UP ); [fTotalDLField setStringValue: [NSString stringForSpeed: downloadRate]]; [fTotalULField setStringValue: [NSString stringForSpeed: uploadRate]]; diff --git a/macosx/Torrent.m b/macosx/Torrent.m index 3fa10ab4f..33b9e4d81 100644 --- a/macosx/Torrent.m +++ b/macosx/Torrent.m @@ -1311,12 +1311,12 @@ void completenessChangeCallback(tr_torrent * torrent, tr_completeness status, vo - (CGFloat) downloadRate { - return fStat->rateDownload; + return fStat->pieceDownloadSpeed; } - (CGFloat) uploadRate { - return fStat->rateUpload; + return fStat->pieceUploadSpeed; } - (CGFloat) totalRate -- 2.40.0