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:
Arvid Norberg 2008-05-05 17:08:14 +00:00
parent d15573ecc2
commit e09457e4ab
6 changed files with 61 additions and 2 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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
};

View File

@ -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;

View File

@ -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);

View File

@ -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