packet pool fixups (#1682)

packet pool fixups
This commit is contained in:
Arvid Norberg 2017-02-10 20:54:26 -05:00 committed by GitHub
parent cc9f40bff9
commit ff22c68df8
3 changed files with 45 additions and 27 deletions

View File

@ -35,7 +35,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#include "libtorrent/aux_/throw.hpp"
#include "libtorrent/aux_/vector.hpp" #include "libtorrent/aux_/vector.hpp"
#include "libtorrent/aux_/numeric_cast.hpp"
#include "libtorrent/assert.hpp"
namespace libtorrent namespace libtorrent
{ {
@ -84,26 +87,33 @@ namespace libtorrent
// deleter for std::unique_ptr // deleter for std::unique_ptr
void operator()(packet* p) const void operator()(packet* p) const
{ {
TORRENT_ASSERT(p != nullptr);
p->~packet(); p->~packet();
std::free(p); std::free(p);
} }
}; };
inline packet* create_packet(int size) inline packet* create_packet(int const size)
{ {
packet* p = static_cast<packet*>(std::malloc(sizeof(packet) + size)); packet* p = static_cast<packet*>(std::malloc(sizeof(packet) + size));
if (p == nullptr) aux::throw_ex<std::bad_alloc>();
new (p) packet(); new (p) packet();
p->allocated = aux::numeric_cast<std::uint16_t>(size);
return p; return p;
} }
using packet_ptr = std::unique_ptr<packet, packet_deleter>; using packet_ptr = std::unique_ptr<packet, packet_deleter>;
template<int ALLOCATE_SIZE>
struct TORRENT_EXTRA_EXPORT packet_slab struct TORRENT_EXTRA_EXPORT packet_slab
{ {
static const int allocate_size{ ALLOCATE_SIZE }; int const allocate_size;
explicit packet_slab(std::size_t limit) : m_limit(limit) { m_storage.reserve(m_limit); } explicit packet_slab(std::size_t const limit, int const alloc_size)
: allocate_size(alloc_size)
, m_limit(limit)
{
m_storage.reserve(m_limit);
}
packet_slab(const packet_slab&) = delete; packet_slab(const packet_slab&) = delete;
@ -115,17 +125,18 @@ namespace libtorrent
packet_ptr alloc() packet_ptr alloc()
{ {
if (m_storage.empty()) if (m_storage.empty()) return packet_ptr(create_packet(allocate_size));
return packet_ptr(create_packet(allocate_size));
else
{
auto ret = std::move(m_storage.back()); auto ret = std::move(m_storage.back());
m_storage.pop_back(); m_storage.pop_back();
return ret; return ret;
} }
void decay()
{
if (m_storage.empty()) return;
m_storage.erase(m_storage.end()-1);
} }
void flush() { m_storage.clear(); }
private: private:
const std::size_t m_limit; const std::size_t m_limit;
aux::vector<packet_ptr, std::size_t> m_storage; aux::vector<packet_ptr, std::size_t> m_storage;
@ -142,7 +153,6 @@ namespace libtorrent
TORRENT_ASSERT(allocate <= std::numeric_limits<std::uint16_t>::max()); TORRENT_ASSERT(allocate <= std::numeric_limits<std::uint16_t>::max());
packet_ptr p{ alloc(allocate) }; packet_ptr p{ alloc(allocate) };
p->allocated = static_cast<std::uint16_t>(allocate);
return p.release(); return p.release();
} }
@ -153,34 +163,36 @@ namespace libtorrent
if (p == nullptr) return; if (p == nullptr) return;
packet_ptr pp(p); // takes ownership and may auto free if slab container does not move it packet_ptr pp(p); // takes ownership and may auto free if slab container does not move it
std::size_t allocated = pp->allocated; int const allocated = pp->allocated;
if (allocated <= m_syn_slab.allocate_size) { m_syn_slab.try_push_back(pp); } if (allocated == m_syn_slab.allocate_size) { m_syn_slab.try_push_back(pp); }
else if (allocated <= m_mtu_floor_slab.allocate_size) { m_mtu_floor_slab.try_push_back(pp); } else if (allocated == m_mtu_floor_slab.allocate_size) { m_mtu_floor_slab.try_push_back(pp); }
else if (allocated <= m_mtu_ceiling_slab.allocate_size) { m_mtu_ceiling_slab.try_push_back(pp); } else if (allocated == m_mtu_ceiling_slab.allocate_size) { m_mtu_ceiling_slab.try_push_back(pp); }
} }
//TODO: call from utp manager to flush mem // periodically free up some of the cached packets
void flush() void decay()
{ {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
m_syn_slab.flush(); m_syn_slab.decay();
m_mtu_floor_slab.flush(); m_mtu_floor_slab.decay();
m_mtu_ceiling_slab.flush(); m_mtu_ceiling_slab.decay();
} }
private: private:
packet_ptr alloc(int allocate) packet_ptr alloc(int const allocate)
{ {
if (allocate <= m_syn_slab.allocate_size) { return m_syn_slab.alloc(); } if (allocate <= m_syn_slab.allocate_size) { return m_syn_slab.alloc(); }
else if (allocate <= m_mtu_floor_slab.allocate_size) { return m_mtu_floor_slab.alloc(); } else if (allocate <= m_mtu_floor_slab.allocate_size) { return m_mtu_floor_slab.alloc(); }
else if (allocate <= m_mtu_ceiling_slab.allocate_size) { return m_mtu_ceiling_slab.alloc(); } else if (allocate <= m_mtu_ceiling_slab.allocate_size) { return m_mtu_ceiling_slab.alloc(); }
return packet_ptr(create_packet(allocate)); return packet_ptr(create_packet(allocate));
} }
packet_slab<sizeof(utp_header)> m_syn_slab{ 50 }; static int const mtu_floor_size = TORRENT_INET_MIN_MTU - TORRENT_IPV4_HEADER - TORRENT_UDP_HEADER;
packet_slab<(TORRENT_INET_MIN_MTU - TORRENT_IPV4_HEADER - TORRENT_UDP_HEADER)> m_mtu_floor_slab{ 100 }; static int const mtu_ceiling_size = TORRENT_ETHERNET_MTU - TORRENT_IPV4_HEADER - TORRENT_UDP_HEADER;
packet_slab<(TORRENT_ETHERNET_MTU - TORRENT_IPV4_HEADER - TORRENT_UDP_HEADER)> m_mtu_ceiling_slab{ 50 }; packet_slab m_syn_slab{ 10, sizeof(utp_header) };
packet_slab m_mtu_floor_slab{ 10, mtu_floor_size };
packet_slab m_mtu_ceiling_slab{ 10 , mtu_ceiling_size };
}; };
} }

View File

@ -122,6 +122,7 @@ namespace libtorrent
packet *acquire_packet(int allocate) { return m_packet_pool.acquire(allocate); } packet *acquire_packet(int allocate) { return m_packet_pool.acquire(allocate); }
void release_packet(packet *p) { m_packet_pool.release(p); } void release_packet(packet *p) { m_packet_pool.release(p); }
void decay() { m_packet_pool.decay(); }
private: private:
// explicitly disallow assignment, to silence msvc warning // explicitly disallow assignment, to silence msvc warning

View File

@ -3151,6 +3151,11 @@ namespace aux {
update_dht_announce_interval(); update_dht_announce_interval();
#endif #endif
m_utp_socket_manager.decay();
#ifdef TORRENT_USE_OPENSSL
m_ssl_utp_socket_manager.decay();
#endif
int tick_interval_ms = int(total_milliseconds(now - m_last_second_tick)); int tick_interval_ms = int(total_milliseconds(now - m_last_second_tick));
m_last_second_tick = now; m_last_second_tick = now;
m_tick_residual += tick_interval_ms - 1000; m_tick_residual += tick_interval_ms - 1000;