support disk I/O priority setting

This commit is contained in:
Arvid Norberg 2010-01-23 03:02:32 +00:00
parent 9e98bfd204
commit a046850130
12 changed files with 82 additions and 8 deletions

View File

@ -95,6 +95,7 @@
* added support for storing per-peer rate limits across reconnects
* improved fallocate support
* fixed magnet link issue when using resume data
* support disk I/O priority settings
release 0.14.9

View File

@ -99,6 +99,13 @@ void bind_session_settings()
.def_readwrite("disk_cache_algorithm", &session_settings::disk_cache_algorithm)
.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("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")

View File

@ -3718,6 +3718,8 @@ session_settings
int max_suggest_pieces;
bool drop_skipped_requests;
bool low_prio_disk;
};
``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
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
===========

View File

@ -253,6 +253,7 @@ namespace libtorrent
{
disk_io_thread(io_service& ios
, boost::function<void()> const& queue_callback
, file_pool& fp
, int block_size = 16 * 1024);
~disk_io_thread();
@ -399,6 +400,10 @@ namespace libtorrent
// exist anymore, and crash. This prevents that.
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 m_disk_io_thread;
};

View File

@ -241,6 +241,12 @@ namespace libtorrent
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:
#ifdef TORRENT_WINDOWS

View File

@ -52,7 +52,7 @@ namespace libtorrent
{
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
, int m, error_code& ec);
@ -60,12 +60,15 @@ namespace libtorrent
void release(std::string const& p);
void resize(int size);
int size_limit() const { return m_size; }
void set_low_prio_io(bool b) { m_low_prio_io = b; }
private:
file_pool(file_pool const&);
void remove_oldest();
int m_size;
bool m_low_prio_io;
struct lru_file_entry
{

View File

@ -185,6 +185,7 @@ namespace libtorrent
, allow_i2p_mixed(false)
, max_suggest_pieces(10)
, drop_skipped_requests(false)
, low_prio_disk(true)
{}
// 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
// request queue has been received, will be considered lost
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

View File

@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/invariant_check.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/error.hpp"
#include "libtorrent/file_pool.hpp"
#include <boost/scoped_array.hpp>
#include <boost/bind.hpp>
@ -280,6 +281,7 @@ namespace libtorrent
disk_io_thread::disk_io_thread(io_service& ios
, boost::function<void()> const& queue_callback
, file_pool& fp
, int block_size)
: disk_buffer_pool(block_size)
, m_abort(false)
@ -289,6 +291,7 @@ namespace libtorrent
, m_ios(ios)
, m_queue_callback(queue_callback)
, m_work(io_service::work(m_ios))
, m_file_pool(fp)
, m_disk_io_thread(boost::bind(&disk_io_thread::thread_fun, this))
{
#ifdef TORRENT_DISK_STATS
@ -1570,7 +1573,21 @@ namespace libtorrent
TORRENT_ASSERT(s.cache_size >= 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_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;
}
case disk_io_job::abort_torrent:

View File

@ -80,6 +80,15 @@ namespace libtorrent
m_files.erase(i);
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());
e.mode = m;
}
@ -126,10 +135,16 @@ namespace libtorrent
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)
{
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();
i != m_files.end();)

View File

@ -175,6 +175,7 @@ namespace libtorrent
set.cache_buffer_chunk_size = 128;
set.read_cache_line_size = 512;
set.write_cache_line_size = 512;
set.low_prio_disk = false;
// one hour expiration
set.cache_expiry = 60 * 60;

View File

@ -403,7 +403,7 @@ namespace aux {
, m_files(40)
, 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_download_rate(peer_connection::download_channel)
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
@ -1016,7 +1016,10 @@ namespace aux {
#ifndef TORRENT_DISABLE_MLOCK
|| m_settings.lock_disk_cache != s.lock_disk_cache
#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;
// if queuing settings were changed, recalculate
@ -1037,7 +1040,6 @@ namespace aux {
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;
// replace all occurances of '\n' with ' '.
std::string::iterator i = m_settings.user_agent.begin();

View File

@ -243,7 +243,7 @@ void run_elevator_test()
{
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, ""
, 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;
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::intrusive_ptr<piece_manager> pm = new piece_manager(dummy, info
, 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;
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::intrusive_ptr<piece_manager> pm = new piece_manager(dummy, info
, test_path, fp, io, default_storage_constructor, storage_mode);