Skip to content

Commit

Permalink
libtorrent: Disable instrumentation properly
Browse files Browse the repository at this point in the history
This commit ejects all non-thread instrumentation code from the compiler when libtorrent is configured with --disable-instrumentation

It also removes the unused --disable-instrumentation configure option for rtorrent.

Update README with instructions for disabling instrumentation since the feature is now stable.
  • Loading branch information
stickz committed Jul 13, 2024
1 parent 1e60798 commit d59ee80
Show file tree
Hide file tree
Showing 13 changed files with 77 additions and 28 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Expand Down
2 changes: 2 additions & 0 deletions libtorrent/src/data/chunk_list.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down
7 changes: 6 additions & 1 deletion libtorrent/src/data/hash_check_queue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
Expand All @@ -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);

Expand Down
9 changes: 8 additions & 1 deletion libtorrent/src/protocol/peer_connection_base.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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),
Expand Down Expand Up @@ -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;
}
Expand All @@ -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.
Expand Down
14 changes: 14 additions & 0 deletions libtorrent/src/protocol/request_list.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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] = {
Expand All @@ -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 <>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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<int, queues_type::iterator> itr =
queue_bucket_find_if_in_any(m_queues, request_list_same_piece(piece));
Expand Down Expand Up @@ -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;
}
Expand All @@ -339,7 +349,9 @@ RequestList::finished() {

m_delegator->transfer_list()->finished(transfer);

#ifdef LT_INSTRUMENTATION
instrumentation_update(INSTRUMENTATION_TRANSFER_REQUESTS_FINISHED, 1);
#endif
}

void
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions libtorrent/src/protocol/request_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename Type>
static void destroy(Type& obj);
Expand Down
4 changes: 4 additions & 0 deletions libtorrent/src/torrent/bitfield.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
11 changes: 10 additions & 1 deletion libtorrent/src/torrent/chunk_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion libtorrent/src/torrent/peer/peer_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down
8 changes: 8 additions & 0 deletions libtorrent/src/utils/instrumentation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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
}

}
7 changes: 4 additions & 3 deletions libtorrent/src/utils/instrumentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@

#ifndef LIBTORRENT_UTILS_INSTRUMENTATION_H
#define LIBTORRENT_UTILS_INSTRUMENTATION_H

#include lt_tr1_array

#include <algorithm>
Expand All @@ -47,6 +46,7 @@
namespace torrent {

enum instrumentation_enum {
#ifdef LT_INSTRUMENTATION
INSTRUMENTATION_MEMORY_BITFIELDS,
INSTRUMENTATION_MEMORY_CHUNK_USAGE,
INSTRUMENTATION_MEMORY_CHUNK_COUNT,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -103,6 +105,7 @@ enum instrumentation_enum {
INSTRUMENTATION_TRANSFER_REQUESTS_CHOKED_TOTAL,

INSTRUMENTATION_TRANSFER_PEER_INFO_UNACCOUNTED,
#endif

INSTRUMENTATION_MAX_SIZE
};
Expand All @@ -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
}

}
Expand Down
Loading

0 comments on commit d59ee80

Please sign in to comment.