Changeset 3864


Ignore:
Timestamp:
Nov 18, 2007, 1:00:49 AM (15 years ago)
Author:
charles
Message:

reintroduce the "SWIFT" algorithm

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/torrent-inspector.c

    r3861 r3864  
    3737#include "util.h"
    3838
    39 #define UPDATE_INTERVAL_MSEC 1500
     39#define UPDATE_INTERVAL_MSEC 2000
    4040
    4141/****
     
    362362        case TR_PEER_STATUS_PEER_IS_CHOKED:       text = _( "Peer is Choked" ); break;
    363363        case TR_PEER_STATUS_CLIENT_IS_CHOKED:     text = _( "Choked" ); break;
    364         case TR_PEER_STATUS_CLIENT_IS_INTERESTED: text = _( "Choked and Interested" ); break;
     364        case TR_PEER_STATUS_CLIENT_IS_INTERESTED: text = _( "Choked & Interested" ); break;
    365365        case TR_PEER_STATUS_READY:                text = _( "Ready" ); break;
    366366        case TR_PEER_STATUS_REQUEST_SENT:         text = _( "Request Sent" ); break;
    367367        case TR_PEER_STATUS_ACTIVE           :    text = _( "Active" ); break;
     368        case TR_PEER_STATUS_ACTIVE_AND_CHOKED:    text = _( "Active & Choked" ); break;
    368369        default:                                  text = "BUG"; break;
    369370    }
  • trunk/libtransmission/clients.c

    r3735 r3864  
    409409            isprint( id[6] ) && isprint( id[7] ) )
    410410        {
    411             tr_asprintf( &ret, "unknown client (%c%c%c%c%c%c%c%c)",
     411            tr_asprintf( &ret, "%c%c%c%c%c%c%c%c",
    412412                  id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7] );
    413413        }
    414414        else
    415415        {
    416             tr_asprintf( &ret, "unknown client (0x%02x%02x%02x%02x%02x%02x%02x%02x)",
     416            tr_asprintf( &ret, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
    417417                  id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7] );
    418418        }
  • trunk/libtransmission/peer-mgr-private.h

    r3861 r3864  
    2828    ENCRYPTION_PREFERENCE_NO
    2929};
     30
     31/**
     32*** The "SWIFT" system is described by Karthik Tamilmani,
     33*** Vinay Pai, and Alexander Mohr of Stony Brook University
     34*** in their paper "SWIFT: A System With Incentives For Trading"
     35*** http://citeseer.ist.psu.edu/tamilmani04swift.html
     36***
     37*** More SWIFT constants are defined in peer-mgr.c
     38**/
     39
     40/**
     41 * Use SWIFT?
     42 */
     43static const int SWIFT_ENABLED = 1;
     44
     45/**
     46 * For every byte the peer uploads to us,
     47 * allow them to download this many bytes from us
     48 */
     49static const double SWIFT_REPAYMENT_RATIO = 1.33;
     50
    3051
    3152typedef struct tr_peer
     
    6788    double rateToClient;
    6889    double rateToPeer;
     90
     91    int64_t credit;
    6992}
    7093tr_peer;
  • trunk/libtransmission/peer-mgr.c

    r3861 r3864  
    4040#include "utils.h"
    4141
     42/**
     43*** The "SWIFT" system is described by Karthik Tamilmani,
     44*** Vinay Pai, and Alexander Mohr of Stony Brook University
     45*** in their paper "SWIFT: A System With Incentives For Trading"
     46*** http://citeseer.ist.psu.edu/tamilmani04swift.html
     47***
     48*** More SWIFT constants are defined in peer-mgr-private.h
     49**/
     50
     51/**
     52 * Allow new peers to download this many bytes from
     53 * us when getting started.  This can prevent gridlock
     54 * with other peers using tit-for-tat algorithms
     55 */
     56static const int SWIFT_INITIAL_CREDIT = 64 * 1024; /* 64 KiB */
     57
     58/**
     59 * We expend a fraction of our torrent's total upload speed
     60 * on largesse by uniformly distributing free credit to
     61 * all of our peers.  This too helps prevent gridlock.
     62 */
     63static const double SWIFT_LARGESSE = 0.10; /* 10% of our UL */
     64
     65/**
     66 * How frequently to extend largesse-based credit
     67 */
     68static const int SWIFT_PERIOD_MSEC = 5000;
     69
     70
    4271enum
    4372{
     
    115144    tr_timer * rechokeTimer;
    116145    tr_timer * refillTimer;
     146    tr_timer * swiftTimer;
    117147    tr_torrent * tor;
    118148    tr_bitfield * requested;
     
    315345    tr_peer * p;
    316346    p = tr_new0( tr_peer, 1 );
     347    p->credit = SWIFT_INITIAL_CREDIT;
    317348    p->rcToClient = tr_rcInit( );
    318349    p->rcToPeer = tr_rcInit( );
     
    398429    tr_timerFree( &t->rechokeTimer );
    399430    tr_timerFree( &t->refillTimer );
     431    tr_timerFree( &t->swiftTimer );
    400432
    401433    tr_bitfieldFree( t->requested );
     
    11681200static int reconnectPulse( void * vtorrent );
    11691201static int rechokePulse( void * vtorrent );
     1202static int swiftPulse( void * vtorrent );
    11701203
    11711204void
     
    11821215    assert( ( t->isRunning != 0 ) == ( t->reconnectTimer != NULL ) );
    11831216    assert( ( t->isRunning != 0 ) == ( t->rechokeTimer != NULL ) );
     1217    assert( ( t->isRunning != 0 ) == ( t->swiftTimer != NULL ) );
    11841218
    11851219    if( !t->isRunning )
     
    11951229                                       RECHOKE_PERIOD_MSEC );
    11961230
     1231        t->swiftTimer = tr_timerNew( t->manager->handle,
     1232                                     swiftPulse, t,
     1233                                     SWIFT_PERIOD_MSEC );
     1234
    11971235        reconnectPulse( t );
    11981236
    11991237        rechokePulse( t );
     1238
     1239        swiftPulse( t );
    12001240    }
    12011241
     
    12111251    tr_timerFree( &t->rechokeTimer );
    12121252    tr_timerFree( &t->reconnectTimer );
     1253    tr_timerFree( &t->swiftTimer );
    12131254
    12141255    /* disconnect the peers. */
     
    14781519{
    14791520    /* FIXME: tweak this? */
    1480     return ( 1 * peer->rateToPeer )
    1481          + ( 1 * peer->rateToClient );
     1521    return /* 1 * peer->rateToPeer )
     1522         +*/ ( 1 * peer->rateToClient );
    14821523}
    14831524
     
    15311572    torrentLock( t );
    15321573    rechoke( t );
     1574    torrentUnlock( t );
     1575    return TRUE;
     1576}
     1577
     1578/***
     1579****
     1580***/
     1581
     1582static int
     1583swiftPulse( void * vtorrent )
     1584{
     1585    Torrent * t = vtorrent;
     1586    torrentLock( t );
     1587
     1588    if( !tr_torrentIsSeed( t->tor ) )
     1589    {
     1590        int i;
     1591        int peerCount = 0;
     1592        int deadbeatCount = 0;
     1593        tr_peer ** peers = getConnectedPeers( t, &peerCount );
     1594        tr_peer ** deadbeats = tr_new( tr_peer*, peerCount );
     1595
     1596        for( i=0; i<peerCount; ++i ) {
     1597            tr_peer * peer = peers[i];
     1598            if( peer->credit < 0 )
     1599                deadbeats[deadbeatCount++] =  peer;
     1600        }
     1601
     1602        if( deadbeatCount )
     1603        {
     1604            const double ul_KiBsec = tr_rcRate( t->tor->upload );
     1605            const double ul_KiB = ul_KiBsec * (SWIFT_PERIOD_MSEC/1000.0);
     1606            const double ul_bytes = ul_KiB * 1024;
     1607            const double freeCreditTotal = ul_bytes * SWIFT_LARGESSE;
     1608            const int freeCreditPerPeer = (int)( freeCreditTotal / deadbeatCount );
     1609            for( i=0; i<deadbeatCount; ++i )
     1610                deadbeats[i]->credit = freeCreditPerPeer;
     1611            tordbg( t, "%d deadbeats, "
     1612                       "who are each being granted %d bytes' credit "
     1613                       "for a total of %.1f KiB, "
     1614                       "%d%% of the torrent's ul speed %.1f\n",
     1615                deadbeatCount, freeCreditPerPeer,
     1616                ul_KiBsec*SWIFT_LARGESSE, (int)(SWIFT_LARGESSE*100), ul_KiBsec );
     1617        }
     1618
     1619        tr_free( deadbeats );
     1620        tr_free( peers );
     1621    }
     1622
    15331623    torrentUnlock( t );
    15341624    return TRUE;
  • trunk/libtransmission/peer-msgs.c

    r3861 r3864  
    10351035    tor->downloadedCur += byteCount;
    10361036    msgs->info->pieceDataActivityDate = time( NULL );
     1037    msgs->info->credit += (int)(byteCount * SWIFT_REPAYMENT_RATIO);
    10371038    tr_rcTransferred( msgs->info->rcToClient, byteCount );
    10381039    tr_rcTransferred( tor->download, byteCount );
     
    12561257    tor->uploadedCur += byteCount;
    12571258    msgs->info->pieceDataActivityDate = time( NULL );
     1259    msgs->info->credit -= byteCount;
    12581260    tr_rcTransferred( msgs->info->rcToPeer, byteCount );
    12591261    tr_rcTransferred( tor->upload, byteCount );
     
    14411443{
    14421444    /* don't let our outbuffer get too large */
    1443     return tr_peerIoWriteBytesWaiting( msgs->io ) < 4096;
     1445    if( tr_peerIoWriteBytesWaiting( msgs->io ) > 4096 )
     1446        return FALSE;
     1447
     1448    /* SWIFT */
     1449    if( SWIFT_ENABLED && !tr_torrentIsSeed( msgs->torrent )
     1450                      && ( msgs->info->credit < 0 ) )
     1451        return FALSE;
     1452
     1453    return TRUE;
    14441454}
    14451455
     
    14931503
    14941504    else if( ( time(NULL) - peer->pieceDataActivityDate ) < 3 )
    1495         peer->status = TR_PEER_STATUS_ACTIVE;
    1496 
    1497     else if( peer->clientIsChoked )
    1498         peer->status = TR_PEER_STATUS_CLIENT_IS_CHOKED;
     1505        peer->status = peer->clientIsChoked
     1506                       ? TR_PEER_STATUS_ACTIVE_AND_CHOKED
     1507                       : TR_PEER_STATUS_ACTIVE;
    14991508
    15001509    else if( peer->peerIsChoked )
    15011510        peer->status = TR_PEER_STATUS_PEER_IS_CHOKED;
    15021511
     1512    else if( peer->clientIsChoked )
     1513        peer->status = peer->clientIsInterested
     1514                       ? TR_PEER_STATUS_CLIENT_IS_INTERESTED
     1515                       : TR_PEER_STATUS_CLIENT_IS_CHOKED;
     1516
    15031517    else if( msgs->clientAskedFor != NULL )
    15041518        peer->status = TR_PEER_STATUS_REQUEST_SENT;
    1505 
    1506     else if( peer->clientIsInterested )
    1507         peer->status = TR_PEER_STATUS_CLIENT_IS_INTERESTED;
    15081519
    15091520    else
  • trunk/libtransmission/ratecontrol.c

    r3845 r3864  
    3030#include "utils.h"
    3131
    32 #define GRANULARITY_MSEC 100
     32#define GRANULARITY_MSEC 250
    3333#define SHORT_INTERVAL_MSEC 3000
    3434#define LONG_INTERVAL_MSEC 6000
     
    109109        max = r->limit;
    110110        kb = max>cur ? max-cur : 0;
    111         bytes = (size_t)(kb * 1024u);
     111        bytes = (size_t)(kb * 1024);
    112112
    113113        tr_lockUnlock( (tr_lock*)r->lock );
  • trunk/libtransmission/transmission.h

    r3861 r3864  
    692692    TR_PEER_STATUS_READY,
    693693    TR_PEER_STATUS_REQUEST_SENT,
    694     TR_PEER_STATUS_ACTIVE
     694    TR_PEER_STATUS_ACTIVE,
     695    TR_PEER_STATUS_ACTIVE_AND_CHOKED
    695696}
    696697tr_peer_status;
Note: See TracChangeset for help on using the changeset viewer.