Exemple #1
0
static void
allocateBandwidth (tr_bandwidth  * b,
                   tr_priority_t   parent_priority,
                   tr_direction    dir,
                   unsigned int    period_msec,
                   tr_ptrArray   * peer_pool)
{
    const tr_priority_t priority = MAX (parent_priority, b->priority);

    assert (tr_isBandwidth (b));
    assert (tr_isDirection (dir));

    /* set the available bandwidth */
    if (b->band[dir].isLimited)
    {
        const uint64_t nextPulseSpeed = b->band[dir].desiredSpeed_Bps;
        b->band[dir].bytesLeft = (unsigned int)(nextPulseSpeed * period_msec) / 1000u;
    }

    /* add this bandwidth's peer, if any, to the peer pool */
    if (b->peer != NULL) {
        b->peer->priority = priority;
        tr_ptrArrayAppend (peer_pool, b->peer);
    }

    /* traverse & repeat for the subtree */
    if (1) {
        int i;
        struct tr_bandwidth ** children = (struct tr_bandwidth**) tr_ptrArrayBase (&b->children);
        const int n = tr_ptrArraySize (&b->children);
        for (i=0; i<n; ++i)
            allocateBandwidth (children[i], priority, dir, period_msec, peer_pool);
    }
}
Exemple #2
0
void
tr_bandwidthUsed( tr_bandwidth  * b,
                  tr_direction    dir,
                  size_t          byteCount,
                  tr_bool         isPieceData,
                  uint64_t        now )
{
    struct tr_band * band;

    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    band = &b->band[dir];

    if( band->isLimited && isPieceData )
        band->bytesLeft -= MIN( band->bytesLeft, byteCount );

#ifdef DEBUG_DIRECTION
if( ( dir == DEBUG_DIRECTION ) && ( band->isLimited ) )
fprintf( stderr, "%p consumed %5zu bytes of %5s data... was %6zu, now %6zu left\n",
         b, byteCount, (isPieceData?"piece":"raw"), oldBytesLeft, band->bytesLeft );
#endif

    bytesUsed( now, &band->raw, byteCount );

    if( isPieceData )
        bytesUsed( now, &band->piece, byteCount );

    if( b->parent != NULL )
        tr_bandwidthUsed( b->parent, dir, byteCount, isPieceData, now );
}
Exemple #3
0
int
tr_sessionGetSpeedLimit( const tr_session * session, tr_direction dir )
{
    assert( tr_isSession( session ) );
    assert( tr_isDirection( dir ) );

    return session->speedLimit[dir];
}
Exemple #4
0
unsigned int
tr_bandwidthGetPieceSpeed_Bps( const tr_bandwidth * b, const uint64_t now, const tr_direction dir )
{
    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    return getSpeed_Bps( &b->band[dir].piece, HISTORY_MSEC, now );
}
Exemple #5
0
double
tr_bandwidthGetPieceSpeed( const tr_bandwidth * b, tr_direction dir )
{
    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    return getSpeed( &b->band[dir].piece, HISTORY_MSEC );
}
Exemple #6
0
tr_bool
tr_sessionIsSpeedLimitEnabled( const tr_session * session, tr_direction dir )
{
    assert( tr_isSession( session ) );
    assert( tr_isDirection( dir ) );

    return session->isSpeedLimited[dir];
}
Exemple #7
0
tr_bool
tr_bandwidthIsLimited( const tr_bandwidth  * b,
                       tr_direction          dir )
{
    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    return b->band[dir].isLimited;
}
Exemple #8
0
double
tr_bandwidthGetDesiredSpeed( const tr_bandwidth  * b,
                             tr_direction          dir )
{
    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    return b->band[dir].desiredSpeed;
}
Exemple #9
0
void
tr_bandwidthSetDesiredSpeed( tr_bandwidth  * b,
                             tr_direction    dir,
                             double          desiredSpeed )
{
    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    b->band[dir].desiredSpeed = desiredSpeed; 
}
Exemple #10
0
void
tr_bandwidthSetLimited( tr_bandwidth  * b,
                        tr_direction    dir,
                        tr_bool         isLimited )
{
    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    b->band[dir].isLimited = isLimited;
}
Exemple #11
0
void
tr_bandwidthHonorParentLimits( tr_bandwidth  * b,
                               tr_direction    dir,
                               tr_bool         honorParentLimits )
{
    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    b->band[dir].honorParentLimits = honorParentLimits;
}
Exemple #12
0
void
tr_sessionSetSpeedLimit( tr_session    * session,
                         tr_direction    dir,
                         int             desiredSpeed )
{
    assert( tr_isSession( session ) );
    assert( tr_isDirection( dir ) );

    session->speedLimit[dir] = desiredSpeed;
    updateBandwidth( session, dir );
}
Exemple #13
0
void
tr_sessionSetSpeedLimitEnabled( tr_session      * session,
                                tr_direction      dir,
                                tr_bool           isLimited )
{
    assert( tr_isSession( session ) );
    assert( tr_isDirection( dir ) );

    session->isSpeedLimited[dir] = isLimited;
    updateBandwidth( session, dir );
}
Exemple #14
0
static void
allocateBandwidth( tr_bandwidth  * b,
                   tr_priority_t   parent_priority,
                   tr_direction    dir,
                   unsigned int    period_msec,
                   tr_ptrArray   * peer_pool )
{
    tr_priority_t priority;

    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    /* set the available bandwidth */
    if( b->band[dir].isLimited )
    {
        const unsigned int nextPulseSpeed = b->band[dir].desiredSpeed_Bps;
        b->band[dir].bytesLeft = ( nextPulseSpeed * period_msec ) / 1000u;

#ifdef DEBUG_DIRECTION
        if( dir == DEBUG_DIRECTION )
                fprintf( stderr, "bandwidth %p currentPieceSpeed(%5.2f of %5.2f) desiredSpeed(%5.2f), allocating %d\n",
                         b, currentSpeed, tr_bandwidthGetRawSpeed( b, dir ), desiredSpeed,
                         b->band[dir].bytesLeft );
#endif
    }

    priority = MAX( parent_priority, b->priority );

    /* add this bandwidth's peer, if any, to the peer pool */
    if( b->peer != NULL ) {
        b->peer->priority = priority;
        tr_ptrArrayAppend( peer_pool, b->peer );
    }

#ifdef DEBUG_DIRECTION
if( ( dir == DEBUG_DIRECTION ) && ( n > 1 ) )
fprintf( stderr, "bandwidth %p has %d peers\n", b, n );
#endif

    /* traverse & repeat for the subtree */
    if( 1 ) {
        int i;
        struct tr_bandwidth ** children = (struct tr_bandwidth**) tr_ptrArrayBase( &b->children );
        const int n = tr_ptrArraySize( &b->children );
        for( i=0; i<n; ++i )
            allocateBandwidth( children[i], priority, dir, period_msec, peer_pool );
    }
}
Exemple #15
0
void
tr_peerIoSetEnabled( tr_peerIo    * io,
                     tr_direction   dir,
                     tr_bool        isEnabled )
{
    const short event = dir == TR_UP ? EV_WRITE : EV_READ;

    assert( tr_isPeerIo( io ) );
    assert( tr_isDirection( dir ) );
    assert( tr_amInEventThread( io->session ) );
    assert( io->session->events != NULL );

    if( isEnabled )
        event_enable( io, event );
    else
        event_disable( io, event );
}
Exemple #16
0
static void
allocateBandwidth( tr_bandwidth  * b,
                   tr_direction    dir,
                   int             period_msec,
                   tr_ptrArray   * peer_pool )
{
    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    /* set the available bandwidth */
    if( b->band[dir].isLimited )
    {
        const double desiredSpeed = b->band[dir].desiredSpeed;
        const double nextPulseSpeed = desiredSpeed;
        b->band[dir].bytesLeft = MAX( 0.0, nextPulseSpeed * 1024.0 * period_msec / 1000.0 );

#ifdef DEBUG_DIRECTION
        if( dir == DEBUG_DIRECTION )
                fprintf( stderr, "bandwidth %p currentPieceSpeed(%5.2f of %5.2f) desiredSpeed(%5.2f), allocating %5.2f\n",
                         b, currentSpeed, tr_bandwidthGetRawSpeed( b, dir ), desiredSpeed,
                         b->band[dir].bytesLeft/1024.0 );
#endif
    }

    /* traverse & repeat for the subtree */
    {
        int i;
        const int n = tr_ptrArraySize( b->peers );
        for( i=0; i<n; ++i )
            tr_ptrArrayAppend( peer_pool, tr_ptrArrayNth( b->peers, i ) );
    }

#ifdef DEBUG_DIRECTION
if( ( dir == DEBUG_DIRECTION ) && ( n > 1 ) )
fprintf( stderr, "bandwidth %p has %d peers\n", b, n );
#endif

    /* all children should reallocate too */
    if( 1 ) {
        int i, n=0;
        struct tr_bandwidth ** children = (struct tr_bandwidth**) tr_ptrArrayPeek( b->children, &n );
        for( i=0; i<n; ++i )
            allocateBandwidth( children[i], dir, period_msec, peer_pool );
    }
}
Exemple #17
0
unsigned int
tr_bandwidthClamp( const tr_bandwidth  * b,
                   tr_direction          dir,
                   unsigned int          byteCount )
{
    assert( tr_isBandwidth( b ) );
    assert( tr_isDirection( dir ) );

    if( b )
    {
        if( b->band[dir].isLimited )
            byteCount = MIN( byteCount, b->band[dir].bytesLeft );

        if( b->parent && b->band[dir].honorParentLimits )
            byteCount = tr_bandwidthClamp( b->parent, dir, byteCount );
    }

    return byteCount;
}
Exemple #18
0
int
tr_peerIoFlush( tr_peerIo  * io, tr_direction dir, size_t limit )
{
    int bytesUsed = 0;

    assert( tr_isPeerIo( io ) );
    assert( tr_isDirection( dir ) );

    if( io->hasFinishedConnecting )
    {
        if( dir == TR_DOWN )
            bytesUsed = tr_peerIoTryRead( io, limit );
        else
            bytesUsed = tr_peerIoTryWrite( io, limit );
    }

    dbgmsg( io, "flushing peer-io, hasFinishedConnecting %d, direction %d, limit %zu, bytesUsed %d", (int)io->hasFinishedConnecting, (int)dir, limit, bytesUsed );
    return bytesUsed;
}
Exemple #19
0
static unsigned int
bandwidthClamp (const tr_bandwidth  * b,
                uint64_t              now,
                tr_direction          dir,
                unsigned int          byteCount)
{
  assert (tr_isBandwidth (b));
  assert (tr_isDirection (dir));

  if (b)
    {
      if (b->band[dir].isLimited)
        {
          byteCount = MIN (byteCount, b->band[dir].bytesLeft);

          /* if we're getting close to exceeding the speed limit,
           * clamp down harder on the bytes available */
          if (byteCount > 0)
            {
              double current;
              double desired;
              double r;

              if (now == 0)
                now = tr_time_msec ();

              current = tr_bandwidthGetRawSpeed_Bps (b, now, TR_DOWN);
              desired = tr_bandwidthGetDesiredSpeed_Bps (b, TR_DOWN);
              r = desired >= 1 ? current / desired : 0;

                   if (r > 1.0) byteCount = 0;
              else if (r > 0.9) byteCount *= 0.8;
              else if (r > 0.8) byteCount *= 0.9;
            }
        }

      if (b->parent && b->band[dir].honorParentLimits && (byteCount > 0))
        byteCount = bandwidthClamp (b->parent, now, dir, byteCount);
    }

  return byteCount;
}