forked from premiere/premiere-libtorrent
take an estimate of the IP ACK traffic into account when rate limiting (allows setting rate limits closer to the capacity)
This commit is contained in:
parent
d15573ecc2
commit
e09457e4ab
|
@ -76,6 +76,8 @@ struct history_entry
|
|||
history_entry(intrusive_ptr<PeerConnection> p, weak_ptr<Torrent> t
|
||||
, int a, ptime exp)
|
||||
: expires_at(exp), amount(a), peer(p), tor(t) {}
|
||||
history_entry(int a, ptime exp)
|
||||
: expires_at(exp), amount(a), peer(), tor() {}
|
||||
ptime expires_at;
|
||||
int amount;
|
||||
intrusive_ptr<PeerConnection> peer;
|
||||
|
@ -111,6 +113,7 @@ struct bandwidth_manager
|
|||
: m_ios(ios)
|
||||
, m_history_timer(m_ios)
|
||||
, m_limit(bandwidth_limit::inf)
|
||||
, m_drain_quota(0)
|
||||
, m_current_quota(0)
|
||||
, m_channel(channel)
|
||||
, m_in_hand_out_bandwidth(false)
|
||||
|
@ -123,6 +126,14 @@ struct bandwidth_manager
|
|||
#endif
|
||||
}
|
||||
|
||||
void drain(int bytes)
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
TORRENT_ASSERT(bytes >= 0);
|
||||
m_drain_quota += bytes;
|
||||
if (m_drain_quota > m_limit * 5) m_drain_quota = m_limit * 5;
|
||||
}
|
||||
|
||||
void throttle(int limit)
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
@ -288,6 +299,7 @@ private:
|
|||
<< std::endl;
|
||||
#endif
|
||||
intrusive_ptr<PeerConnection> c = e.peer;
|
||||
if (!c) continue;
|
||||
shared_ptr<Torrent> t = e.tor.lock();
|
||||
l.unlock();
|
||||
if (!c->is_disconnecting()) c->expire_bandwidth(m_channel, e.amount);
|
||||
|
@ -329,6 +341,15 @@ private:
|
|||
|
||||
if (amount <= 0) return;
|
||||
|
||||
if (m_drain_quota > 0)
|
||||
{
|
||||
int drain_amount = (std::min)(m_drain_quota, amount);
|
||||
m_drain_quota -= drain_amount;
|
||||
amount -= drain_amount;
|
||||
add_history_entry(history_entry<PeerConnection, Torrent>(
|
||||
drain_amount, now + bw_window_size));
|
||||
}
|
||||
|
||||
queue_t tmp;
|
||||
while (!m_queue.empty() && amount > 0)
|
||||
{
|
||||
|
@ -433,6 +454,10 @@ private:
|
|||
// the rate limit (bytes per second)
|
||||
int m_limit;
|
||||
|
||||
// bytes to drain without handing out to a peer
|
||||
// used to deduct the IP overhead
|
||||
int m_drain_quota;
|
||||
|
||||
// the sum of all recently handed out bandwidth blocks
|
||||
int m_current_quota;
|
||||
|
||||
|
|
|
@ -230,6 +230,8 @@ namespace libtorrent
|
|||
const stat& statistics() const { return m_statistics; }
|
||||
void add_stat(size_type downloaded, size_type uploaded);
|
||||
|
||||
void calc_ip_overhead();
|
||||
|
||||
// is called once every second by the main loop
|
||||
void second_tick(float tick_interval);
|
||||
|
||||
|
|
|
@ -140,6 +140,24 @@ namespace libtorrent
|
|||
m_stat[upload_protocol].add(bytes_protocol);
|
||||
}
|
||||
|
||||
// calculate ip protocol overhead
|
||||
void calc_ip_overhead()
|
||||
{
|
||||
// traffic balance is the number of bytes we downloaded
|
||||
// more than we uploaded
|
||||
int traffic_balance = m_stat[download_protocol].counter()
|
||||
+ m_stat[download_payload].counter()
|
||||
- m_stat[upload_protocol].counter()
|
||||
- m_stat[upload_payload].counter();
|
||||
if (traffic_balance > 0)
|
||||
m_stat[upload_ip_protocol].add(traffic_balance / 20);
|
||||
else
|
||||
m_stat[download_ip_protocol].add(-traffic_balance / 20);
|
||||
}
|
||||
|
||||
int upload_ip_overhead() const { return m_stat[upload_ip_protocol].counter(); }
|
||||
int download_ip_overhead() const { return m_stat[download_ip_protocol].counter(); }
|
||||
|
||||
// should be called once every second
|
||||
void second_tick(float tick_interval)
|
||||
{
|
||||
|
@ -150,13 +168,15 @@ namespace libtorrent
|
|||
float upload_rate() const
|
||||
{
|
||||
return m_stat[upload_payload].rate()
|
||||
+ m_stat[upload_protocol].rate();
|
||||
+ m_stat[upload_protocol].rate()
|
||||
+ m_stat[upload_ip_protocol].rate();
|
||||
}
|
||||
|
||||
float download_rate() const
|
||||
{
|
||||
return m_stat[download_payload].rate()
|
||||
+ m_stat[download_protocol].rate();
|
||||
+ m_stat[download_protocol].rate()
|
||||
+ m_stat[download_ip_protocol].rate();
|
||||
}
|
||||
|
||||
float upload_payload_rate() const
|
||||
|
@ -198,8 +218,10 @@ namespace libtorrent
|
|||
{
|
||||
upload_payload,
|
||||
upload_protocol,
|
||||
upload_ip_protocol,
|
||||
download_payload,
|
||||
download_protocol,
|
||||
download_ip_protocol,
|
||||
num_channels
|
||||
};
|
||||
|
||||
|
|
|
@ -2413,6 +2413,11 @@ namespace libtorrent
|
|||
m_packet_size = packet_size;
|
||||
}
|
||||
|
||||
void peer_connection::calc_ip_overhead()
|
||||
{
|
||||
m_statistics.calc_ip_overhead();
|
||||
}
|
||||
|
||||
void peer_connection::second_tick(float tick_interval)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
|
|
@ -1046,6 +1046,10 @@ namespace aux {
|
|||
++i;
|
||||
}
|
||||
|
||||
// drain the IP overhead from the bandwidth limiters
|
||||
m_download_channel.drain(m_stat.download_ip_overhead());
|
||||
m_upload_channel.drain(m_stat.upload_ip_overhead());
|
||||
|
||||
m_stat.second_tick(tick_interval);
|
||||
|
||||
|
||||
|
|
|
@ -3489,6 +3489,7 @@ namespace libtorrent
|
|||
{
|
||||
peer_connection* p = *i;
|
||||
++i;
|
||||
p->calc_ip_overhead();
|
||||
m_stat += p->statistics();
|
||||
// updates the peer connection's ul/dl bandwidth
|
||||
// resource requests
|
||||
|
|
Loading…
Reference in New Issue