support disk I/O priority setting
This commit is contained in:
parent
9e98bfd204
commit
a046850130
|
@ -95,6 +95,7 @@
|
||||||
* added support for storing per-peer rate limits across reconnects
|
* added support for storing per-peer rate limits across reconnects
|
||||||
* improved fallocate support
|
* improved fallocate support
|
||||||
* fixed magnet link issue when using resume data
|
* fixed magnet link issue when using resume data
|
||||||
|
* support disk I/O priority settings
|
||||||
|
|
||||||
release 0.14.9
|
release 0.14.9
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,13 @@ void bind_session_settings()
|
||||||
.def_readwrite("disk_cache_algorithm", &session_settings::disk_cache_algorithm)
|
.def_readwrite("disk_cache_algorithm", &session_settings::disk_cache_algorithm)
|
||||||
.def_readwrite("read_cache_line_size", &session_settings::read_cache_line_size)
|
.def_readwrite("read_cache_line_size", &session_settings::read_cache_line_size)
|
||||||
.def_readwrite("write_cache_line_size", &session_settings::write_cache_line_size)
|
.def_readwrite("write_cache_line_size", &session_settings::write_cache_line_size)
|
||||||
|
.def_readwrite("optimistic_disk_retry", &session_settings::optimistic_disk_retry)
|
||||||
|
.def_readwrite("disable_hash_checks", &session_settings::disable_hash_checks)
|
||||||
|
.def_readwrite("allow_reordered_disk_operations", &session_settings::allow_reordered_disk_operations)
|
||||||
|
.def_readwrite("allow_i2p_mixed", &session_settings::allow_i2p_mixed)
|
||||||
|
.def_readwrite("max_suggest_pieces", &session_settings::max_suggest_pieces)
|
||||||
|
.def_readwrite("drop_skipped_requests", &session_settings::drop_skipped_requests)
|
||||||
|
.def_readwrite("low_prio_disk", &session_settings::low_prio_disk)
|
||||||
;
|
;
|
||||||
|
|
||||||
enum_<proxy_settings::proxy_type>("proxy_type")
|
enum_<proxy_settings::proxy_type>("proxy_type")
|
||||||
|
|
|
@ -3718,6 +3718,8 @@ session_settings
|
||||||
int max_suggest_pieces;
|
int max_suggest_pieces;
|
||||||
|
|
||||||
bool drop_skipped_requests;
|
bool drop_skipped_requests;
|
||||||
|
|
||||||
|
bool low_prio_disk;
|
||||||
};
|
};
|
||||||
|
|
||||||
``user_agent`` this is the client identification to the tracker.
|
``user_agent`` this is the client identification to the tracker.
|
||||||
|
@ -4180,6 +4182,13 @@ BitComet peers silently ignoring some requests. It may cause problems
|
||||||
at high rates, and high level of reordering in the uploading peer, that's
|
at high rates, and high level of reordering in the uploading peer, that's
|
||||||
why it's disabled by default.
|
why it's disabled by default.
|
||||||
|
|
||||||
|
``low_prio_disk`` determines if the disk I/O should use a normal
|
||||||
|
or low priority policy. This defaults to true, which means that
|
||||||
|
it's low priority by default. Other processes doing disk I/O will
|
||||||
|
normally take priority in this mode. This is meant to improve the
|
||||||
|
overall responsiveness of the system while downloading in the
|
||||||
|
background. For high-performance server setups, this might not
|
||||||
|
be desirable.
|
||||||
|
|
||||||
pe_settings
|
pe_settings
|
||||||
===========
|
===========
|
||||||
|
|
|
@ -253,6 +253,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
disk_io_thread(io_service& ios
|
disk_io_thread(io_service& ios
|
||||||
, boost::function<void()> const& queue_callback
|
, boost::function<void()> const& queue_callback
|
||||||
|
, file_pool& fp
|
||||||
, int block_size = 16 * 1024);
|
, int block_size = 16 * 1024);
|
||||||
~disk_io_thread();
|
~disk_io_thread();
|
||||||
|
|
||||||
|
@ -399,6 +400,10 @@ namespace libtorrent
|
||||||
// exist anymore, and crash. This prevents that.
|
// exist anymore, and crash. This prevents that.
|
||||||
boost::optional<io_service::work> m_work;
|
boost::optional<io_service::work> m_work;
|
||||||
|
|
||||||
|
// reference to the file_pool which is a member of
|
||||||
|
// the session_impl object
|
||||||
|
file_pool& m_file_pool;
|
||||||
|
|
||||||
// thread for performing blocking disk io operations
|
// thread for performing blocking disk io operations
|
||||||
thread m_disk_io_thread;
|
thread m_disk_io_thread;
|
||||||
};
|
};
|
||||||
|
|
|
@ -241,6 +241,12 @@ namespace libtorrent
|
||||||
|
|
||||||
size_type phys_offset(size_type offset);
|
size_type phys_offset(size_type offset);
|
||||||
|
|
||||||
|
#ifdef TORRENT_WINDOWS
|
||||||
|
HANDLE native_handle() const { return m_file_handle; }
|
||||||
|
#else
|
||||||
|
int native_handle() const { return m_fd; }
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#ifdef TORRENT_WINDOWS
|
#ifdef TORRENT_WINDOWS
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
struct TORRENT_EXPORT file_pool : boost::noncopyable
|
struct TORRENT_EXPORT file_pool : boost::noncopyable
|
||||||
{
|
{
|
||||||
file_pool(int size = 40): m_size(size) {}
|
file_pool(int size = 40): m_size(size), m_low_prio_io(true) {}
|
||||||
|
|
||||||
boost::shared_ptr<file> open_file(void* st, std::string const& p
|
boost::shared_ptr<file> open_file(void* st, std::string const& p
|
||||||
, int m, error_code& ec);
|
, int m, error_code& ec);
|
||||||
|
@ -60,12 +60,15 @@ namespace libtorrent
|
||||||
void release(std::string const& p);
|
void release(std::string const& p);
|
||||||
void resize(int size);
|
void resize(int size);
|
||||||
int size_limit() const { return m_size; }
|
int size_limit() const { return m_size; }
|
||||||
|
void set_low_prio_io(bool b) { m_low_prio_io = b; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
file_pool(file_pool const&);
|
||||||
|
|
||||||
void remove_oldest();
|
void remove_oldest();
|
||||||
|
|
||||||
int m_size;
|
int m_size;
|
||||||
|
bool m_low_prio_io;
|
||||||
|
|
||||||
struct lru_file_entry
|
struct lru_file_entry
|
||||||
{
|
{
|
||||||
|
|
|
@ -185,6 +185,7 @@ namespace libtorrent
|
||||||
, allow_i2p_mixed(false)
|
, allow_i2p_mixed(false)
|
||||||
, max_suggest_pieces(10)
|
, max_suggest_pieces(10)
|
||||||
, drop_skipped_requests(false)
|
, drop_skipped_requests(false)
|
||||||
|
, low_prio_disk(true)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// this is the user agent that will be sent to the tracker
|
// this is the user agent that will be sent to the tracker
|
||||||
|
@ -675,6 +676,13 @@ namespace libtorrent
|
||||||
// satisfied after the equivalence of the entire
|
// satisfied after the equivalence of the entire
|
||||||
// request queue has been received, will be considered lost
|
// request queue has been received, will be considered lost
|
||||||
bool drop_skipped_requests;
|
bool drop_skipped_requests;
|
||||||
|
|
||||||
|
// if this is set to true, the disk I/O will be
|
||||||
|
// run at lower-than-normal priority. This is
|
||||||
|
// intended to make the machine more responsive
|
||||||
|
// to foreground tasks, while bittorrent runs
|
||||||
|
// in the background
|
||||||
|
bool low_prio_disk;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
|
|
@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/invariant_check.hpp"
|
#include "libtorrent/invariant_check.hpp"
|
||||||
#include "libtorrent/error_code.hpp"
|
#include "libtorrent/error_code.hpp"
|
||||||
#include "libtorrent/error.hpp"
|
#include "libtorrent/error.hpp"
|
||||||
|
#include "libtorrent/file_pool.hpp"
|
||||||
#include <boost/scoped_array.hpp>
|
#include <boost/scoped_array.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
|
@ -280,6 +281,7 @@ namespace libtorrent
|
||||||
|
|
||||||
disk_io_thread::disk_io_thread(io_service& ios
|
disk_io_thread::disk_io_thread(io_service& ios
|
||||||
, boost::function<void()> const& queue_callback
|
, boost::function<void()> const& queue_callback
|
||||||
|
, file_pool& fp
|
||||||
, int block_size)
|
, int block_size)
|
||||||
: disk_buffer_pool(block_size)
|
: disk_buffer_pool(block_size)
|
||||||
, m_abort(false)
|
, m_abort(false)
|
||||||
|
@ -289,6 +291,7 @@ namespace libtorrent
|
||||||
, m_ios(ios)
|
, m_ios(ios)
|
||||||
, m_queue_callback(queue_callback)
|
, m_queue_callback(queue_callback)
|
||||||
, m_work(io_service::work(m_ios))
|
, m_work(io_service::work(m_ios))
|
||||||
|
, m_file_pool(fp)
|
||||||
, m_disk_io_thread(boost::bind(&disk_io_thread::thread_fun, this))
|
, m_disk_io_thread(boost::bind(&disk_io_thread::thread_fun, this))
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_DISK_STATS
|
#ifdef TORRENT_DISK_STATS
|
||||||
|
@ -1570,7 +1573,21 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(s.cache_size >= 0);
|
TORRENT_ASSERT(s.cache_size >= 0);
|
||||||
TORRENT_ASSERT(s.cache_expiry > 0);
|
TORRENT_ASSERT(s.cache_expiry > 0);
|
||||||
|
|
||||||
|
#if defined TORRENT_WINDOWS
|
||||||
|
if (m_settings.low_prio_disk != s.low_prio_disk)
|
||||||
|
{
|
||||||
|
m_file_pool.set_low_prio_io(s.low_prio_disk);
|
||||||
|
// we need to close all files, since the prio
|
||||||
|
// only takes affect when files are opened
|
||||||
|
m_file_pool.release(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
m_settings = s;
|
m_settings = s;
|
||||||
|
m_file_pool.resize(m_settings.file_pool_size);
|
||||||
|
#if defined __APPLE__ && defined __MACH__ && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
|
||||||
|
setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_THREAD
|
||||||
|
, m_settings.low_prio_disk ? IOPOL_THROTTLE : IOPOL_DEFAULT);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case disk_io_job::abort_torrent:
|
case disk_io_job::abort_torrent:
|
||||||
|
|
|
@ -80,6 +80,15 @@ namespace libtorrent
|
||||||
m_files.erase(i);
|
m_files.erase(i);
|
||||||
return boost::shared_ptr<file>();
|
return boost::shared_ptr<file>();
|
||||||
}
|
}
|
||||||
|
#ifdef TORRENT_WINDOWS
|
||||||
|
if (m_low_prio_io)
|
||||||
|
{
|
||||||
|
FILE_IO_PRIORITY_HINT_INFO priorityHint;
|
||||||
|
priorityHint.PriorityHint = IoPriorityHintLow;
|
||||||
|
result = SetFileInformationByHandle(e.file_ptr->native_handle(),
|
||||||
|
FileIoPriorityHintInfo, &priorityHint, sizeof(PriorityHint));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
TORRENT_ASSERT(e.file_ptr->is_open());
|
TORRENT_ASSERT(e.file_ptr->is_open());
|
||||||
e.mode = m;
|
e.mode = m;
|
||||||
}
|
}
|
||||||
|
@ -126,10 +135,16 @@ namespace libtorrent
|
||||||
if (i != m_files.end()) m_files.erase(i);
|
if (i != m_files.end()) m_files.erase(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// closes files belonging to the specified
|
||||||
|
// storage. If 0 is passed, all files are closed
|
||||||
void file_pool::release(void* st)
|
void file_pool::release(void* st)
|
||||||
{
|
{
|
||||||
mutex::scoped_lock l(m_mutex);
|
mutex::scoped_lock l(m_mutex);
|
||||||
TORRENT_ASSERT(st != 0);
|
if (st == 0)
|
||||||
|
{
|
||||||
|
m_files.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (file_set::iterator i = m_files.begin();
|
for (file_set::iterator i = m_files.begin();
|
||||||
i != m_files.end();)
|
i != m_files.end();)
|
||||||
|
|
|
@ -175,6 +175,7 @@ namespace libtorrent
|
||||||
set.cache_buffer_chunk_size = 128;
|
set.cache_buffer_chunk_size = 128;
|
||||||
set.read_cache_line_size = 512;
|
set.read_cache_line_size = 512;
|
||||||
set.write_cache_line_size = 512;
|
set.write_cache_line_size = 512;
|
||||||
|
set.low_prio_disk = false;
|
||||||
// one hour expiration
|
// one hour expiration
|
||||||
set.cache_expiry = 60 * 60;
|
set.cache_expiry = 60 * 60;
|
||||||
|
|
||||||
|
|
|
@ -403,7 +403,7 @@ namespace aux {
|
||||||
, m_files(40)
|
, m_files(40)
|
||||||
, m_io_service()
|
, m_io_service()
|
||||||
, m_alerts(m_io_service)
|
, m_alerts(m_io_service)
|
||||||
, m_disk_thread(m_io_service, boost::bind(&session_impl::on_disk_queue, this))
|
, m_disk_thread(m_io_service, boost::bind(&session_impl::on_disk_queue, this), m_files)
|
||||||
, m_half_open(m_io_service)
|
, m_half_open(m_io_service)
|
||||||
, m_download_rate(peer_connection::download_channel)
|
, m_download_rate(peer_connection::download_channel)
|
||||||
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||||
|
@ -1016,7 +1016,10 @@ namespace aux {
|
||||||
#ifndef TORRENT_DISABLE_MLOCK
|
#ifndef TORRENT_DISABLE_MLOCK
|
||||||
|| m_settings.lock_disk_cache != s.lock_disk_cache
|
|| m_settings.lock_disk_cache != s.lock_disk_cache
|
||||||
#endif
|
#endif
|
||||||
|| m_settings.use_read_cache != s.use_read_cache)
|
|| m_settings.use_read_cache != s.use_read_cache
|
||||||
|
|| m_settings.allow_reordered_disk_operations != s.allow_reordered_disk_operations
|
||||||
|
|| m_settings.file_pool_size != s.file_pool_size
|
||||||
|
|| m_settings.low_prio_disk != s.low_prio_disk)
|
||||||
update_disk_io_thread = true;
|
update_disk_io_thread = true;
|
||||||
|
|
||||||
// if queuing settings were changed, recalculate
|
// if queuing settings were changed, recalculate
|
||||||
|
@ -1037,7 +1040,6 @@ namespace aux {
|
||||||
m_disk_thread.add_job(j);
|
m_disk_thread.add_job(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_files.resize(m_settings.file_pool_size);
|
|
||||||
if (!s.auto_upload_slots) m_allowed_upload_slots = m_max_uploads;
|
if (!s.auto_upload_slots) m_allowed_upload_slots = m_max_uploads;
|
||||||
// replace all occurances of '\n' with ' '.
|
// replace all occurances of '\n' with ' '.
|
||||||
std::string::iterator i = m_settings.user_agent.begin();
|
std::string::iterator i = m_settings.user_agent.begin();
|
||||||
|
|
|
@ -243,7 +243,7 @@ void run_elevator_test()
|
||||||
|
|
||||||
{
|
{
|
||||||
error_code ec;
|
error_code ec;
|
||||||
disk_io_thread dio(ios, &nop);
|
disk_io_thread dio(ios, &nop, fp);
|
||||||
boost::intrusive_ptr<piece_manager> pm(new piece_manager(boost::shared_ptr<void>(), ti, ""
|
boost::intrusive_ptr<piece_manager> pm(new piece_manager(boost::shared_ptr<void>(), ti, ""
|
||||||
, fp, dio, &create_test_storage, storage_mode_sparse));
|
, fp, dio, &create_test_storage, storage_mode_sparse));
|
||||||
|
|
||||||
|
@ -379,7 +379,7 @@ void run_storage_tests(boost::intrusive_ptr<torrent_info> info
|
||||||
{
|
{
|
||||||
file_pool fp;
|
file_pool fp;
|
||||||
libtorrent::asio::io_service ios;
|
libtorrent::asio::io_service ios;
|
||||||
disk_io_thread io(ios, boost::function<void()>());
|
disk_io_thread io(ios, boost::function<void()>(), fp);
|
||||||
boost::shared_ptr<int> dummy(new int);
|
boost::shared_ptr<int> dummy(new int);
|
||||||
boost::intrusive_ptr<piece_manager> pm = new piece_manager(dummy, info
|
boost::intrusive_ptr<piece_manager> pm = new piece_manager(dummy, info
|
||||||
, test_path, fp, io, default_storage_constructor, storage_mode);
|
, test_path, fp, io, default_storage_constructor, storage_mode);
|
||||||
|
@ -601,7 +601,7 @@ void test_check_files(std::string const& test_path
|
||||||
|
|
||||||
file_pool fp;
|
file_pool fp;
|
||||||
libtorrent::asio::io_service ios;
|
libtorrent::asio::io_service ios;
|
||||||
disk_io_thread io(ios, boost::function<void()>());
|
disk_io_thread io(ios, boost::function<void()>(), fp);
|
||||||
boost::shared_ptr<int> dummy(new int);
|
boost::shared_ptr<int> dummy(new int);
|
||||||
boost::intrusive_ptr<piece_manager> pm = new piece_manager(dummy, info
|
boost::intrusive_ptr<piece_manager> pm = new piece_manager(dummy, info
|
||||||
, test_path, fp, io, default_storage_constructor, storage_mode);
|
, test_path, fp, io, default_storage_constructor, storage_mode);
|
||||||
|
|
Loading…
Reference in New Issue