diff --git a/ChangeLog b/ChangeLog index c5596a17e..58775df1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * make disk cache pool allocator configurable * fix library ABI to not depend on logging being enabled * use hex encoding instead of base32 in create_magnet_uri * include name, save_path and torrent_file in torrent_status, for improved performance diff --git a/docs/manual.rst b/docs/manual.rst index 6ace67167..fb8ee7cf8 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -4654,6 +4654,12 @@ session_settings bool ban_web_seeds; int max_http_recv_buffer_size; + + bool support_share_mode; + bool support_merkle_torrents; + bool report_redundant_bytes; + std::string handshake_client_version; + bool use_disk_cache_pool; }; ``version`` is automatically set to the libtorrent version you're using @@ -5556,6 +5562,23 @@ RAM buffers when downloading stuff over HTTP. Specifically when specifying a URL to a .torrent file when adding a torrent or when announcing to an HTTP tracker. The default is 2 MiB. +``support_share_mode`` enables or disables the share mode extension. This is +enabled by default. + +``support_merkle_torrents`` enables or disables the merkle tree torrent support. +This is enabled by default. + +``report_redundant_bytes`` enables or disables reporting redundant bytes to the tracker. +This is enabled by default. + +``handshake_client_version`` is the client name advertized in the peer handshake. If +set to an empty string, the user_agent string is used. + +``use_disk_cache_pool`` enables using a pool allocator for disk cache blocks. This is +disabled by default. Enabling it makes the cache perform better at high throughput. +It also makes the cache less likely and slower at returning memory back to the system +once allocated. + pe_settings =========== diff --git a/include/libtorrent/disk_buffer_pool.hpp b/include/libtorrent/disk_buffer_pool.hpp index b61a37e88..63896bb5c 100644 --- a/include/libtorrent/disk_buffer_pool.hpp +++ b/include/libtorrent/disk_buffer_pool.hpp @@ -38,6 +38,10 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/session_settings.hpp" #include "libtorrent/allocator.hpp" +#ifndef TORRENT_DISABLE_POOL_ALLOCATOR +#include +#endif + #ifdef TORRENT_DISK_STATS #include #endif @@ -97,6 +101,25 @@ namespace libtorrent mutable mutex m_pool_mutex; +#ifndef TORRENT_DISABLE_POOL_ALLOCATOR + // if this is true, all buffers are allocated + // from m_pool. If this is false, all buffers + // are allocated using page_aligned_allocator. + // if the settings change to prefer the other + // allocator, this bool will not switch over + // to match the settings until all buffers have + // been freed. That way, we never have a mixture + // of buffers allocated from different sources. + // in essence, this make the setting only take + // effect after a restart (which seems fine). + // or once the client goes idle for a while. + bool m_using_pool_allocator; + + // memory pool for read and write operations + // and disk cache + boost::pool m_pool; +#endif + #if defined TORRENT_DISK_STATS || defined TORRENT_STATS int m_allocations; #endif diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index 68680c903..ff13a9b29 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -965,6 +965,14 @@ namespace libtorrent // in the peer protocol handshake. If this is empty // the user_agent is used std::string handshake_client_version; + + // if this is true, the disk cache uses a pool allocator + // for disk cache blocks. Enabling this improves + // performance of the disk cache with the side effect + // that the disk cache is less likely and slower at + // returning memory to the kernel when cache pressure + // is low. + bool use_disk_cache_pool; }; #ifndef TORRENT_DISABLE_DHT diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index bd472e503..1dc2e3f2e 100644 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -127,7 +127,7 @@ namespace libtorrent private: // the type of the addr union unsigned is_v6_addr:1; - unsigned unused:1; +// unsigned unused:1; public: // the state this block is in (see block_state_t) unsigned state:2; diff --git a/src/disk_buffer_pool.cpp b/src/disk_buffer_pool.cpp index 196c4a2a7..98cb2360b 100644 --- a/src/disk_buffer_pool.cpp +++ b/src/disk_buffer_pool.cpp @@ -47,6 +47,10 @@ namespace libtorrent disk_buffer_pool::disk_buffer_pool(int block_size) : m_block_size(block_size) , m_in_use(0) +#ifndef TORRENT_DISABLE_POOL_ALLOCATOR + , m_using_pool_allocator(false) + , m_pool(block_size, m_settings.cache_buffer_chunk_size) +#endif { #if defined TORRENT_DISK_STATS || defined TORRENT_STATS m_allocations = 0; @@ -80,7 +84,14 @@ namespace libtorrent if (m_buf_to_category.find(buffer) == m_buf_to_category.end()) return false; #endif +#ifdef TORRENT_DISABLE_POOL_ALLOCATOR return true; +#else + if (m_using_pool_allocator) + return m_pool.is_from(buffer); + else + return true; +#endif } bool disk_buffer_pool::is_disk_buffer(char* buffer) const @@ -94,7 +105,20 @@ namespace libtorrent { mutex::scoped_lock l(m_pool_mutex); TORRENT_ASSERT(m_magic == 0x1337); - char* ret = page_aligned_allocator::malloc(m_block_size); + char* ret; +#ifdef TORRENT_DISABLE_POOL_ALLOCATOR + ret = page_aligned_allocator::malloc(m_block_size); +#else + if (m_using_pool_allocator) + { + ret = (char*)m_pool.malloc(); + m_pool.set_next_size(m_settings.cache_buffer_chunk_size); + } + else + { + ret = page_aligned_allocator::malloc(m_block_size); + } +#endif ++m_in_use; #if TORRENT_USE_MLOCK if (m_settings.lock_disk_cache) @@ -185,13 +209,34 @@ namespace libtorrent #endif } #endif +#ifdef TORRENT_DISABLE_POOL_ALLOCATOR page_aligned_allocator::free(buf); +#else + if (m_using_pool_allocator) + m_pool.free(buf); + else + page_aligned_allocator::free(buf); +#endif --m_in_use; + +#ifndef TORRENT_DISABLE_POOL_ALLOCATOR + // should we switch which allocator to use? + if (m_in_use == 0 && m_settings.use_disk_cache_pool != m_using_pool_allocator) + { + m_pool.release_memory(); + m_using_pool_allocator = m_settings.use_disk_cache_pool; + } +#endif } void disk_buffer_pool::release_memory() { TORRENT_ASSERT(m_magic == 0x1337); +#ifndef TORRENT_DISABLE_POOL_ALLOCATOR + mutex::scoped_lock l(m_pool_mutex); + if (m_using_pool_allocator) + m_pool.release_memory(); +#endif } } diff --git a/src/session.cpp b/src/session.cpp index d53135381..7ac65dc14 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -304,6 +304,9 @@ namespace libtorrent // max 'bottled' http receive buffer/url torrent size set.max_http_recv_buffer_size = 6 * 1024 * 1024; + // the disk cache performs better with the pool allocator + set.use_disk_cache_pool = true; + return set; } @@ -1312,6 +1315,7 @@ namespace libtorrent , support_share_mode(true) , support_merkle_torrents(false) , report_redundant_bytes(true) + , use_disk_cache_pool(false) {} session_settings::~session_settings() {}