prevent read jobs from starving in the disk I/O thread
This commit is contained in:
parent
4a40a13a6c
commit
2dfd1a972b
|
@ -4381,6 +4381,7 @@ session_settings
|
|||
bool smooth_connects;
|
||||
bool always_send_user_agent;
|
||||
bool apply_ip_filter_to_trackers;
|
||||
int read_job_every;
|
||||
};
|
||||
|
||||
``version`` is automatically set to the libtorrent version you're using
|
||||
|
@ -5238,6 +5239,13 @@ IP filter applies to trackers as well as peers. If this is set to false,
|
|||
trackers are exempt from the IP filter (if there is one). If no IP filter
|
||||
is set, this setting is irrelevant.
|
||||
|
||||
``read_job_every`` is used to avoid starvation of read jobs in the disk I/O
|
||||
thread. By default, read jobs are deferred, sorted by physical disk location
|
||||
and serviced once all write jobs have been issued. In scenarios where the
|
||||
download rate is enough to saturate the disk, there's a risk the read jobs will
|
||||
never be serviced. With this setting, every *x* write job, issued in a row, will
|
||||
instead pick one read job off of the sorted queue, where *x* is ``read_job_every``.
|
||||
|
||||
pe_settings
|
||||
===========
|
||||
|
||||
|
|
|
@ -267,6 +267,7 @@ namespace libtorrent
|
|||
, smooth_connects(true)
|
||||
, always_send_user_agent(false)
|
||||
, apply_ip_filter_to_trackers(true)
|
||||
, read_job_every(10)
|
||||
{}
|
||||
|
||||
// libtorrent version. Used for forward binary compatibility
|
||||
|
@ -1064,6 +1065,11 @@ namespace libtorrent
|
|||
// if true, trackers will also be filtered by the IP
|
||||
// filter, otherwise they are exempt
|
||||
bool apply_ip_filter_to_trackers;
|
||||
|
||||
// to avoid write jobs starving read jobs, if this many
|
||||
// write jobs have been taking priority in a row, service
|
||||
// one read job
|
||||
int read_job_every;
|
||||
};
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
|
|
@ -1559,6 +1559,7 @@ namespace libtorrent
|
|||
read_jobs_t::iterator elevator_job_pos = m_sorted_read_jobs.begin();
|
||||
size_type last_elevator_pos = 0;
|
||||
bool need_update_elevator_pos = false;
|
||||
int immediate_jobs_in_row = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1618,7 +1619,14 @@ namespace libtorrent
|
|||
m_queue_time.add_sample(total_microseconds(now - j.start_time));
|
||||
ptime operation_start = now;
|
||||
|
||||
if (!m_jobs.empty())
|
||||
// make sure we don't starve out the read queue by just issuing
|
||||
// write jobs constantly, mix in a read job every now and then
|
||||
// with a configurable ratio
|
||||
bool pick_read_job = m_jobs.empty()
|
||||
|| (immediate_jobs_in_row >= m_settings.read_job_every
|
||||
&& !m_sorted_read_jobs.empty());
|
||||
|
||||
if (!pick_read_job)
|
||||
{
|
||||
// we have a job in the job queue. If it's
|
||||
// a read operation and we are allowed to
|
||||
|
@ -1702,6 +1710,8 @@ namespace libtorrent
|
|||
m_cache_stats.cumulative_job_time += total_milliseconds(now - operation_start);
|
||||
continue;
|
||||
}
|
||||
|
||||
++immediate_jobs_in_row;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1710,6 +1720,8 @@ namespace libtorrent
|
|||
// job queue lock anymore
|
||||
jl.unlock();
|
||||
|
||||
immediate_jobs_in_row = 0;
|
||||
|
||||
TORRENT_ASSERT(!m_sorted_read_jobs.empty());
|
||||
|
||||
// if m_sorted_read_jobs used to be empty,
|
||||
|
|
|
@ -363,6 +363,7 @@ namespace aux {
|
|||
TORRENT_SETTING(integer, smooth_connects)
|
||||
TORRENT_SETTING(boolean, always_send_user_agent)
|
||||
TORRENT_SETTING(boolean, apply_ip_filter_to_trackers)
|
||||
TORRENT_SETTING(integer, read_job_every)
|
||||
};
|
||||
|
||||
#undef TORRENT_SETTING
|
||||
|
|
Loading…
Reference in New Issue