diff --git a/docs/manual.rst b/docs/manual.rst index 6099c3c1e..4a2c7ad15 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -655,8 +655,9 @@ struct has the following members:: int dht_nodes; int dht_node_cache; int dht_torrents; - int dht_global_nodes; + size_type dht_global_nodes; std::vector active_requests; + int dht_total_allocations; }; ``has_incoming_connections`` is false as long as no incoming connections have been @@ -720,6 +721,9 @@ network. ``active_requests`` is a vector of the currently running DHT lookups. +``dht_total_allocations`` is the number of nodes allocated dynamically for a +particular DHT lookup. This represents roughly the amount of memory used +by the DHT. get_cache_status() ------------------ diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 9cf3c33f8..f3627adb9 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -1483,8 +1483,9 @@ int main(int argc, char* argv[]) #ifndef TORRENT_DISABLE_DHT if (show_dht_status) { - snprintf(str, sizeof(str), "DHT nodes: %d DHT cached nodes: %d total DHT size: %"PRId64"\n" - , sess_stat.dht_nodes, sess_stat.dht_node_cache, sess_stat.dht_global_nodes); + snprintf(str, sizeof(str), "DHT nodes: %d DHT cached nodes: %d total DHT size: %"PRId64" total observers: %d\n" + , sess_stat.dht_nodes, sess_stat.dht_node_cache, sess_stat.dht_global_nodes + , sess_stat.dht_total_allocations); out += str; for (std::vector::iterator i = sess_stat.active_requests.begin() diff --git a/include/libtorrent/kademlia/rpc_manager.hpp b/include/libtorrent/kademlia/rpc_manager.hpp index 47e2a157f..fb8fa6eb3 100644 --- a/include/libtorrent/kademlia/rpc_manager.hpp +++ b/include/libtorrent/kademlia/rpc_manager.hpp @@ -89,8 +89,10 @@ public: void check_invariant() const; #endif - boost::pool<>& allocator() const - { return m_pool_allocator; } + void* allocate_observer(); + void free_observer(void* ptr); + + int num_allocated_observers() const { return m_allocated_observers; } private: @@ -112,6 +114,7 @@ private: routing_table& m_table; ptime m_timer; node_id m_random_number; + int m_allocated_observers; bool m_destructing; }; diff --git a/include/libtorrent/kademlia/traversal_algorithm.hpp b/include/libtorrent/kademlia/traversal_algorithm.hpp index 6ad7cde8d..b09601747 100644 --- a/include/libtorrent/kademlia/traversal_algorithm.hpp +++ b/include/libtorrent/kademlia/traversal_algorithm.hpp @@ -66,9 +66,11 @@ struct traversal_algorithm : boost::noncopyable enum flags_t { prevent_request = 1, short_timeout = 2 }; void failed(observer_ptr o, int flags = 0); virtual ~traversal_algorithm(); - boost::pool<>& allocator() const; void status(dht_lookup& l); + void* allocate_observer(); + void free_observer(void* ptr); + virtual char const* name() const { return "traversal_algorithm"; } virtual void start(); diff --git a/include/libtorrent/session_status.hpp b/include/libtorrent/session_status.hpp index 212d80d89..9cb3849f8 100644 --- a/include/libtorrent/session_status.hpp +++ b/include/libtorrent/session_status.hpp @@ -104,6 +104,7 @@ namespace libtorrent int dht_torrents; size_type dht_global_nodes; std::vector active_requests; + int dht_total_allocations; #endif int peerlist_size; diff --git a/src/kademlia/node.cpp b/src/kademlia/node.cpp index bbe03f456..72d06b55e 100644 --- a/src/kademlia/node.cpp +++ b/src/kademlia/node.cpp @@ -366,9 +366,8 @@ namespace TORRENT_LOG(node) << " distance: " << (160 - distance_exp(ih, i->first.id)); #endif - void* ptr = node.m_rpc.allocator().malloc(); + void* ptr = node.m_rpc.allocate_observer(); if (ptr == 0) return; - node.m_rpc.allocator().set_next_size(10); observer_ptr o(new (ptr) announce_observer(algo, i->first.ep(), i->first.id)); #ifdef TORRENT_DEBUG o->m_in_constructor = false; @@ -397,9 +396,8 @@ void node_impl::add_node(udp::endpoint node) { // ping the node, and if we get a reply, it // will be added to the routing table - void* ptr = m_rpc.allocator().malloc(); + void* ptr = m_rpc.allocate_observer(); if (ptr == 0) return; - m_rpc.allocator().set_next_size(10); // create a dummy traversal_algorithm // this is unfortunately necessary for the observer @@ -470,6 +468,7 @@ void node_impl::status(session_status& s) m_table.status(s); s.dht_torrents = int(m_map.size()); s.active_requests.clear(); + s.dht_total_allocations = m_rpc.num_allocated_observers(); for (std::set::iterator i = m_running_requests.begin() , end(m_running_requests.end()); i != end; ++i) { diff --git a/src/kademlia/rpc_manager.cpp b/src/kademlia/rpc_manager.cpp index 62ddc600c..4fac42f70 100644 --- a/src/kademlia/rpc_manager.cpp +++ b/src/kademlia/rpc_manager.cpp @@ -76,9 +76,9 @@ void intrusive_ptr_release(observer const* o) TORRENT_ASSERT(o != 0); if (--o->m_refs == 0) { - boost::pool<>& p = o->m_algorithm->allocator(); + boost::intrusive_ptr ta = o->m_algorithm; (const_cast(o))->~observer(); - p.free(const_cast(o)); + ta->free_observer(const_cast(o)); } } @@ -172,6 +172,7 @@ rpc_manager::rpc_manager(node_id const& our_id , m_table(table) , m_timer(time_now()) , m_random_number(generate_id()) + , m_allocated_observers(0) , m_destructing(false) { std::srand(time(0)); @@ -215,6 +216,21 @@ rpc_manager::~rpc_manager() } } +void* rpc_manager::allocate_observer() +{ + m_pool_allocator.set_next_size(10); + void* ret = m_pool_allocator.malloc(); + if (ret) ++m_allocated_observers; + return ret; +} + +void rpc_manager::free_observer(void* ptr) +{ + if (!ptr) return; + --m_allocated_observers; + m_pool_allocator.free(ptr); +} + #ifdef TORRENT_DEBUG size_t rpc_manager::allocation_size() const { diff --git a/src/kademlia/traversal_algorithm.cpp b/src/kademlia/traversal_algorithm.cpp index b0e028e9a..e355606c4 100644 --- a/src/kademlia/traversal_algorithm.cpp +++ b/src/kademlia/traversal_algorithm.cpp @@ -59,8 +59,7 @@ observer_ptr traversal_algorithm::new_observer(void* ptr void traversal_algorithm::add_entry(node_id const& id, udp::endpoint addr, unsigned char flags) { TORRENT_ASSERT(m_node.m_rpc.allocation_size() >= sizeof(find_data_observer)); - m_node.m_rpc.allocator().set_next_size(10); - void* ptr = m_node.m_rpc.allocator().malloc(); + void* ptr = m_node.m_rpc.allocate_observer(); if (ptr == 0) { #ifdef TORRENT_DHT_VERBOSE_LOGGING @@ -113,9 +112,14 @@ void traversal_algorithm::start() add_requests(); } -boost::pool<>& traversal_algorithm::allocator() const +void* traversal_algorithm::allocate_observer() { - return m_node.m_rpc.allocator(); + return m_node.m_rpc.allocate_observer(); +} + +void traversal_algorithm::free_observer(void* ptr) +{ + m_node.m_rpc.free_observer(ptr); } void traversal_algorithm::traverse(node_id const& id, udp::endpoint addr) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 6e85a79e4..50a07a016 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -3566,6 +3566,7 @@ namespace aux { s.dht_node_cache = 0; s.dht_torrents = 0; s.dht_global_nodes = 0; + s.dht_total_allocations = 0; } #endif