diff --git a/README.md b/README.md index d22b99fd..31b10cc7 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,13 @@ make install ### Installing libtorrent We strongly advise to configure with aligned memory access (`--enable-aligned`) to avoid critical stability issues. +We recommend to configure with instrumentation disabled (`--disable-instrumentation`) to improve performance. This feature has been fixed since version 5.3. We do not recommend using file preload. It's better to leave this decision to the Linux Kernel. You can reduce the overhead of the peer connection protocol, by disabling it entirely at compile time with (`--enable-hosted-mode`). If `pieces.preload.type` is changed from ruTorrent or .rtorrent.rc it will accept the value and ignore it for 100% backwards compatibility. ``` cd libtorrent ./autogen.sh -./configure --prefix=/usr --enable-aligned --enable-hosted-mode +./configure --prefix=/usr --enable-aligned --enable-hosted-mode --disable-instrumentation make -j$(nproc) CXXFLAGS="-O3" make install ``` diff --git a/libtorrent/src/data/chunk_list.cc b/libtorrent/src/data/chunk_list.cc index 00abbc2a..5b68fbfc 100644 --- a/libtorrent/src/data/chunk_list.cc +++ b/libtorrent/src/data/chunk_list.cc @@ -342,12 +342,14 @@ ChunkList::sync_chunks(int flags) { std::iter_swap(itr, split++); } +#ifdef LT_INSTRUMENTATION if (lt_log_is_valid(LOG_INSTRUMENTATION_MINCORE)) { instrumentation_update(INSTRUMENTATION_MINCORE_SYNC_SUCCESS, std::distance(split, m_queue.end())); instrumentation_update(INSTRUMENTATION_MINCORE_SYNC_FAILED, failed); instrumentation_update(INSTRUMENTATION_MINCORE_SYNC_NOT_SYNCED, std::distance(m_queue.begin(), split)); instrumentation_update(INSTRUMENTATION_MINCORE_SYNC_NOT_DEALLOCATED, std::count_if(split, m_queue.end(), std::mem_fun(&ChunkListNode::is_valid))); } +#endif m_queue.erase(split, m_queue.end()); diff --git a/libtorrent/src/data/hash_check_queue.cc b/libtorrent/src/data/hash_check_queue.cc index 8c05daf8..d4006ab1 100644 --- a/libtorrent/src/data/hash_check_queue.cc +++ b/libtorrent/src/data/hash_check_queue.cc @@ -66,9 +66,11 @@ HashCheckQueue::push_back(HashChunk* hash_chunk) { base_type::push_back(hash_chunk); +#ifdef LT_INSTRUMENTATION int64_t size = hash_chunk->chunk()->chunk()->chunk_size(); instrumentation_update(INSTRUMENTATION_MEMORY_HASHING_CHUNK_COUNT, 1); instrumentation_update(INSTRUMENTATION_MEMORY_HASHING_CHUNK_USAGE, size); +#endif pthread_mutex_unlock(&m_lock); } @@ -97,10 +99,11 @@ HashCheckQueue::remove(HashChunk* hash_chunk) { if (itr != end()) { base_type::erase(itr); result = true; - +#ifdef LT_INSTRUMENTATION int64_t size = hash_chunk->chunk()->chunk()->chunk_size(); instrumentation_update(INSTRUMENTATION_MEMORY_HASHING_CHUNK_COUNT, -1); instrumentation_update(INSTRUMENTATION_MEMORY_HASHING_CHUNK_USAGE, -size); +#endif } else { result = false; @@ -121,9 +124,11 @@ HashCheckQueue::perform() { if (!hash_chunk->chunk()->is_loaded()) throw internal_error("HashCheckQueue::perform(): !entry.node->is_loaded()."); +#ifdef LT_INSTRUMENTATION int64_t size = hash_chunk->chunk()->chunk()->chunk_size(); instrumentation_update(INSTRUMENTATION_MEMORY_HASHING_CHUNK_COUNT, -1); instrumentation_update(INSTRUMENTATION_MEMORY_HASHING_CHUNK_USAGE, -size); +#endif pthread_mutex_unlock(&m_lock); diff --git a/libtorrent/src/protocol/peer_connection_base.cc b/libtorrent/src/protocol/peer_connection_base.cc index a1c99f66..96857abd 100644 --- a/libtorrent/src/protocol/peer_connection_base.cc +++ b/libtorrent/src/protocol/peer_connection_base.cc @@ -73,6 +73,8 @@ namespace torrent { +#ifdef LT_INSTRUMENTATION +#ifndef USE_HOSTED_MODE inline void log_mincore_stats_func(bool is_incore, bool new_index, bool& continous) { if (!new_index && is_incore) { @@ -93,6 +95,8 @@ log_mincore_stats_func(bool is_incore, bool new_index, bool& continous) { continous = is_incore; } +#endif +#endif PeerConnectionBase::PeerConnectionBase() : m_download(NULL), @@ -397,9 +401,10 @@ PeerConnectionBase::load_up_chunk() { if (m_upChunk.is_valid() && m_upChunk.index() == m_upPiece.index()) { // Better checking needed. // m_upChunk.chunk()->preload(m_upPiece.offset(), m_upChunk.chunk()->size()); - +#ifdef LT_INSTRUMENTATION if (lt_log_is_valid(LOG_INSTRUMENTATION_MINCORE)) log_mincore_stats_func(m_upChunk.chunk()->is_incore(m_upPiece.offset(), m_upPiece.length()), false, m_incoreContinous); +#endif return; } @@ -416,12 +421,14 @@ PeerConnectionBase::load_up_chunk() { m_encryptBuffer->reset(); } +#ifdef LT_INSTRUMENTATION m_incoreContinous = false; if (lt_log_is_valid(LOG_INSTRUMENTATION_MINCORE)) log_mincore_stats_func(m_upChunk.chunk()->is_incore(m_upPiece.offset(), m_upPiece.length()), true, m_incoreContinous); m_incoreContinous = true; +#endif // Also check if we've already preloaded in the recent past, even // past unmaps. diff --git a/libtorrent/src/protocol/request_list.cc b/libtorrent/src/protocol/request_list.cc index ea81d1ef..61f16a8f 100644 --- a/libtorrent/src/protocol/request_list.cc +++ b/libtorrent/src/protocol/request_list.cc @@ -52,6 +52,7 @@ namespace torrent { +#ifdef LT_INSTRUMENTATION const int request_list_constants::bucket_count; const instrumentation_enum request_list_constants::instrumentation_added[bucket_count] = { @@ -78,6 +79,7 @@ const instrumentation_enum request_list_constants::instrumentation_total[bucket_ INSTRUMENTATION_TRANSFER_REQUESTS_STALLED_TOTAL, INSTRUMENTATION_TRANSFER_REQUESTS_CHOKED_TOTAL }; +#endif // Make inline... template <> @@ -132,7 +134,9 @@ RequestList::delegate(uint32_t maxPieces) { if (transfers.empty()) return pieces; +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_TRANSFER_REQUESTS_DELEGATED, 1); +#endif for (auto& itr : transfers) { m_queues.push_back(bucket_queued, itr); @@ -225,7 +229,9 @@ void RequestList::delay_process_unordered() { m_last_unordered_position = std::min(m_last_unordered_position, unordered_size()); +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_TRANSFER_REQUESTS_FINISHED, m_last_unordered_position); +#endif m_queues.destroy(bucket_unordered, m_queues.begin(bucket_unordered), @@ -254,7 +260,9 @@ RequestList::downloading(const Piece& piece) { if (m_transfer != NULL) throw internal_error("RequestList::downloading(...) m_transfer != NULL."); +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_TRANSFER_REQUESTS_DOWNLOADING, 1); +#endif std::pair itr = queue_bucket_find_if_in_any(m_queues, request_list_same_piece(piece)); @@ -320,7 +328,9 @@ RequestList::downloading(const Piece& piece) { m_transfer = new BlockTransfer(); Block::create_dummy(m_transfer, m_peerChunks->peer_info(), piece); +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_TRANSFER_REQUESTS_UNKNOWN, 1); +#endif return false; } @@ -339,7 +349,9 @@ RequestList::finished() { m_delegator->transfer_list()->finished(transfer); +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_TRANSFER_REQUESTS_FINISHED, 1); +#endif } void @@ -350,7 +362,9 @@ RequestList::skipped() { Block::release(m_transfer); m_transfer = NULL; +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_TRANSFER_REQUESTS_SKIPPED, 1); +#endif } // Data downloaded by this non-leading transfer does not match what we diff --git a/libtorrent/src/protocol/request_list.h b/libtorrent/src/protocol/request_list.h index dab1bdf2..203e2c78 100644 --- a/libtorrent/src/protocol/request_list.h +++ b/libtorrent/src/protocol/request_list.h @@ -54,10 +54,12 @@ class Delegator; struct request_list_constants { static const int bucket_count = 4; +#ifdef LT_INSTRUMENTATION static const torrent::instrumentation_enum instrumentation_added[bucket_count]; static const torrent::instrumentation_enum instrumentation_moved[bucket_count]; static const torrent::instrumentation_enum instrumentation_removed[bucket_count]; static const torrent::instrumentation_enum instrumentation_total[bucket_count]; +#endif template static void destroy(Type& obj); diff --git a/libtorrent/src/torrent/bitfield.cc b/libtorrent/src/torrent/bitfield.cc index 882095b0..92a947a6 100644 --- a/libtorrent/src/torrent/bitfield.cc +++ b/libtorrent/src/torrent/bitfield.cc @@ -69,7 +69,9 @@ Bitfield::allocate() { m_data = new value_type[size_bytes()]; +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_MEMORY_BITFIELDS, (int64_t)size_bytes()); +#endif } void @@ -80,7 +82,9 @@ Bitfield::unallocate() { delete [] m_data; m_data = NULL; +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_MEMORY_BITFIELDS, -(int64_t)size_bytes()); +#endif } void diff --git a/libtorrent/src/torrent/chunk_manager.cc b/libtorrent/src/torrent/chunk_manager.cc index d1531f9e..4b422f8a 100644 --- a/libtorrent/src/torrent/chunk_manager.cc +++ b/libtorrent/src/torrent/chunk_manager.cc @@ -148,20 +148,25 @@ ChunkManager::allocate(uint32_t size, int flags) { try_free_memory((1 * m_maxMemoryUsage) / 4); if (m_memoryUsage + size > m_maxMemoryUsage) { +#ifdef LT_INSTRUMENTATION if (!(flags & allocate_dont_log)) instrumentation_update(INSTRUMENTATION_MINCORE_ALLOC_FAILED, 1); - +#endif return false; } +#ifdef LT_INSTRUMENTATION if (!(flags & allocate_dont_log)) instrumentation_update(INSTRUMENTATION_MINCORE_ALLOCATIONS, size); +#endif m_memoryUsage += size; m_memoryBlockCount++; +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_MEMORY_CHUNK_COUNT, 1); instrumentation_update(INSTRUMENTATION_MEMORY_CHUNK_USAGE, size); +#endif return true; } @@ -171,18 +176,22 @@ ChunkManager::deallocate(uint32_t size, int flags) { if (size > m_memoryUsage) throw internal_error("ChunkManager::deallocate(...) size > m_memoryUsage."); +#ifdef LT_INSTRUMENTATION if (!(flags & allocate_dont_log)) { if (flags & allocate_revert_log) instrumentation_update(INSTRUMENTATION_MINCORE_ALLOCATIONS, -size); else instrumentation_update(INSTRUMENTATION_MINCORE_DEALLOCATIONS, size); } +#endif m_memoryUsage -= size; m_memoryBlockCount--; +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_MEMORY_CHUNK_COUNT, -1); instrumentation_update(INSTRUMENTATION_MEMORY_CHUNK_USAGE, -(int64_t)size); +#endif } void diff --git a/libtorrent/src/torrent/peer/peer_info.cc b/libtorrent/src/torrent/peer/peer_info.cc index 234a2c6c..3908d34c 100644 --- a/libtorrent/src/torrent/peer/peer_info.cc +++ b/libtorrent/src/torrent/peer/peer_info.cc @@ -71,8 +71,9 @@ PeerInfo::PeerInfo(const sockaddr* address) : PeerInfo::~PeerInfo() { // if (m_transferCounter != 0) // throw internal_error("PeerInfo::~PeerInfo() m_transferCounter != 0."); - +#ifdef LT_INSTRUMENTATION instrumentation_update(INSTRUMENTATION_TRANSFER_PEER_INFO_UNACCOUNTED, m_transferCounter); +#endif if (is_blocked()) throw internal_error("PeerInfo::~PeerInfo() peer is blocked."); diff --git a/libtorrent/src/utils/instrumentation.cc b/libtorrent/src/utils/instrumentation.cc index 729b20e2..e279151c 100644 --- a/libtorrent/src/utils/instrumentation.cc +++ b/libtorrent/src/utils/instrumentation.cc @@ -57,6 +57,7 @@ void instrumentation_tick() { // Since the values are updated with __sync_add, they can be read // without any memory barriers. +#ifdef LT_INSTRUMENTATION lt_log_print(LOG_INSTRUMENTATION_MEMORY, "%" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64, instrumentation_values[INSTRUMENTATION_MEMORY_CHUNK_USAGE], @@ -83,6 +84,7 @@ instrumentation_tick() { instrumentation_fetch_and_clear(INSTRUMENTATION_MINCORE_ALLOCATIONS), instrumentation_fetch_and_clear(INSTRUMENTATION_MINCORE_DEALLOCATIONS)); +#endif lt_log_print(LOG_INSTRUMENTATION_POLLING, "%" PRIi64 " %" PRIi64 @@ -101,6 +103,7 @@ instrumentation_tick() { instrumentation_fetch_and_clear(INSTRUMENTATION_POLLING_EVENTS_DISK), instrumentation_fetch_and_clear(INSTRUMENTATION_POLLING_EVENTS_OTHERS)); +#ifdef LT_INSTRUMENTATION lt_log_print(LOG_INSTRUMENTATION_TRANSFERS, "%" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64 " %" PRIi64 @@ -137,10 +140,12 @@ instrumentation_tick() { instrumentation_values[INSTRUMENTATION_TRANSFER_REQUESTS_CHOKED_TOTAL], instrumentation_values[INSTRUMENTATION_TRANSFER_PEER_INFO_UNACCOUNTED]); +#endif } void instrumentation_reset() { +#ifdef LT_INSTRUMENTATION instrumentation_fetch_and_clear(INSTRUMENTATION_MINCORE_INCORE_TOUCHED); instrumentation_fetch_and_clear(INSTRUMENTATION_MINCORE_INCORE_NEW); instrumentation_fetch_and_clear(INSTRUMENTATION_MINCORE_NOT_INCORE_TOUCHED); @@ -155,6 +160,7 @@ instrumentation_reset() { instrumentation_fetch_and_clear(INSTRUMENTATION_MINCORE_ALLOCATIONS); instrumentation_fetch_and_clear(INSTRUMENTATION_MINCORE_DEALLOCATIONS); +#endif instrumentation_fetch_and_clear(INSTRUMENTATION_POLLING_INTERRUPT_POKE); instrumentation_fetch_and_clear(INSTRUMENTATION_POLLING_INTERRUPT_READ_EVENT); @@ -169,6 +175,7 @@ instrumentation_reset() { instrumentation_fetch_and_clear(INSTRUMENTATION_POLLING_EVENTS_DISK); instrumentation_fetch_and_clear(INSTRUMENTATION_POLLING_EVENTS_OTHERS); +#ifdef LT_INSTRUMENTATION instrumentation_fetch_and_clear(INSTRUMENTATION_TRANSFER_REQUESTS_DELEGATED); instrumentation_fetch_and_clear(INSTRUMENTATION_TRANSFER_REQUESTS_DOWNLOADING); instrumentation_fetch_and_clear(INSTRUMENTATION_TRANSFER_REQUESTS_FINISHED); @@ -188,6 +195,7 @@ instrumentation_reset() { instrumentation_fetch_and_clear(INSTRUMENTATION_TRANSFER_REQUESTS_CHOKED_ADDED); instrumentation_fetch_and_clear(INSTRUMENTATION_TRANSFER_REQUESTS_CHOKED_MOVED); instrumentation_fetch_and_clear(INSTRUMENTATION_TRANSFER_REQUESTS_CHOKED_REMOVED); +#endif } } diff --git a/libtorrent/src/utils/instrumentation.h b/libtorrent/src/utils/instrumentation.h index 956429bf..1204f33b 100644 --- a/libtorrent/src/utils/instrumentation.h +++ b/libtorrent/src/utils/instrumentation.h @@ -36,7 +36,6 @@ #ifndef LIBTORRENT_UTILS_INSTRUMENTATION_H #define LIBTORRENT_UTILS_INSTRUMENTATION_H - #include lt_tr1_array #include @@ -47,6 +46,7 @@ namespace torrent { enum instrumentation_enum { +#ifdef LT_INSTRUMENTATION INSTRUMENTATION_MEMORY_BITFIELDS, INSTRUMENTATION_MEMORY_CHUNK_USAGE, INSTRUMENTATION_MEMORY_CHUNK_COUNT, @@ -65,6 +65,7 @@ enum instrumentation_enum { INSTRUMENTATION_MINCORE_ALLOC_FAILED, INSTRUMENTATION_MINCORE_ALLOCATIONS, INSTRUMENTATION_MINCORE_DEALLOCATIONS, +#endif INSTRUMENTATION_POLLING_INTERRUPT_POKE, INSTRUMENTATION_POLLING_INTERRUPT_READ_EVENT, @@ -79,6 +80,7 @@ enum instrumentation_enum { INSTRUMENTATION_POLLING_EVENTS_DISK, INSTRUMENTATION_POLLING_EVENTS_OTHERS, +#ifdef LT_INSTRUMENTATION INSTRUMENTATION_TRANSFER_REQUESTS_DELEGATED, INSTRUMENTATION_TRANSFER_REQUESTS_DOWNLOADING, INSTRUMENTATION_TRANSFER_REQUESTS_FINISHED, @@ -103,6 +105,7 @@ enum instrumentation_enum { INSTRUMENTATION_TRANSFER_REQUESTS_CHOKED_TOTAL, INSTRUMENTATION_TRANSFER_PEER_INFO_UNACCOUNTED, +#endif INSTRUMENTATION_MAX_SIZE }; @@ -125,9 +128,7 @@ instrumentation_initialize() { inline void instrumentation_update(instrumentation_enum type, int64_t change) { -#ifdef LT_INSTRUMENTATION __sync_add_and_fetch(&instrumentation_values[type], change); -#endif } } diff --git a/libtorrent/src/utils/queue_buckets.h b/libtorrent/src/utils/queue_buckets.h index de8584ff..f87764b6 100644 --- a/libtorrent/src/utils/queue_buckets.h +++ b/libtorrent/src/utils/queue_buckets.h @@ -176,8 +176,10 @@ inline void queue_buckets::pop_front(int idx) { queue_at(idx).pop_front(); +#ifdef LT_INSTRUMENTATION instrumentation_update(constants::instrumentation_removed[idx], 1); instrumentation_update(constants::instrumentation_total[idx], -1); +#endif } template @@ -185,8 +187,10 @@ inline void queue_buckets::pop_back(int idx) { queue_at(idx).pop_back(); +#ifdef LT_INSTRUMENTATION instrumentation_update(constants::instrumentation_removed[idx], 1); instrumentation_update(constants::instrumentation_total[idx], -1); +#endif } template @@ -210,8 +214,10 @@ inline void queue_buckets::push_front(int idx, const value_type& value) { queue_at(idx).push_front(value); +#ifdef LT_INSTRUMENTATION instrumentation_update(constants::instrumentation_added[idx], 1); instrumentation_update(constants::instrumentation_total[idx], 1); +#endif } template @@ -219,8 +225,10 @@ inline void queue_buckets::push_back(int idx, const value_type& value) { queue_at(idx).push_back(value); +#ifdef LT_INSTRUMENTATION instrumentation_update(constants::instrumentation_added[idx], 1); instrumentation_update(constants::instrumentation_total[idx], 1); +#endif } template @@ -229,8 +237,10 @@ queue_buckets::take(int idx, iterator itr) { value_type v = *itr; queue_at(idx).erase(itr); +#ifdef LT_INSTRUMENTATION instrumentation_update(constants::instrumentation_removed[idx], 1); instrumentation_update(constants::instrumentation_total[idx], -1); +#endif // TODO: Add 'taken' instrumentation. @@ -246,9 +256,12 @@ queue_buckets::clear(int idx) { template inline void queue_buckets::destroy(int idx, iterator begin, iterator end) { + +#ifdef LT_INSTRUMENTATION difference_type difference = std::distance(begin, end); instrumentation_update(constants::instrumentation_removed[idx], difference); instrumentation_update(constants::instrumentation_total[idx], -difference); +#endif // Consider moving these to a temporary dequeue before releasing: std::for_each(begin, end, std::function(&constants::template destroy)); @@ -259,11 +272,13 @@ template inline void queue_buckets::move_to(int src_idx, iterator src_begin, iterator src_end, int dst_idx) { +#ifdef LT_INSTRUMENTATION difference_type difference = std::distance(src_begin, src_end); instrumentation_update(constants::instrumentation_moved[src_idx], difference); instrumentation_update(constants::instrumentation_total[src_idx], -difference); instrumentation_update(constants::instrumentation_added[dst_idx], difference); instrumentation_update(constants::instrumentation_total[dst_idx], difference); +#endif // TODO: Check for better move operations: if (queue_at(dst_idx).empty() && diff --git a/rtorrent/scripts/common.m4 b/rtorrent/scripts/common.m4 index aaf005e3..d177346b 100644 --- a/rtorrent/scripts/common.m4 +++ b/rtorrent/scripts/common.m4 @@ -199,26 +199,6 @@ AC_DEFUN([TORRENT_ENABLE_ALIGNED], [ ]) ]) - -AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [ - AC_MSG_CHECKING([if instrumentation should be included]) - - AC_ARG_ENABLE(instrumentation, - AC_HELP_STRING([--disable-instrumentation], [disable instrumentation [[default=enabled]]]), - [ - if test "$enableval" = "yes"; then - AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation) - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fi - ],[ - AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation) - AC_MSG_RESULT(yes) - ]) -]) - - AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [ AC_ARG_ENABLE(interrupt-socket, AC_HELP_STRING([--enable-interrupt-socket], [enable interrupt socket [[default=no]]]),