parent
cc9f40bff9
commit
ff22c68df8
|
@ -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));
|
auto ret = std::move(m_storage.back());
|
||||||
else
|
m_storage.pop_back();
|
||||||
{
|
return ret;
|
||||||
auto ret = std::move(m_storage.back());
|
}
|
||||||
m_storage.pop_back();
|
|
||||||
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 };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue