disk write queue watermark fix

This commit is contained in:
Arvid Norberg 2011-02-13 22:27:02 +00:00
parent b664f7faa3
commit 8bb71da401
7 changed files with 24 additions and 15 deletions

View File

@ -506,9 +506,11 @@ void print_peer_info(std::string& out, std::vector<libtorrent::peer_info> const&
, (i->flags & peer_info::on_parole)?'p':'.'
, (i->flags & peer_info::optimistic_unchoke)?'O':'.'
, (i->read_state == peer_info::bw_limit)?'r':
(i->read_state == peer_info::bw_network)?'R':'.'
(i->read_state == peer_info::bw_network)?'R':
(i->read_state == peer_info::bw_disk)?'D':'.'
, (i->write_state == peer_info::bw_limit)?'w':
(i->write_state == peer_info::bw_network)?'W':'.'
(i->write_state == peer_info::bw_network)?'W':
(i->write_state == peer_info::bw_disk)?'D':'.'
, (i->flags & peer_info::snubbed)?'S':'.'
, (i->flags & peer_info::upload_only)?'U':'D'
, (i->flags & peer_info::endgame_mode)?'-':'.'

View File

@ -423,6 +423,9 @@ namespace libtorrent
, int source_type, address const& source);
address const& external_address() const { return m_external_address; }
bool can_write_to_disk() const
{ return m_disk_thread.can_write(); }
// used when posting synchronous function
// calls to session_impl and torrent objects
mutable libtorrent::mutex mut;

View File

@ -303,6 +303,7 @@ namespace libtorrent
// this is used to slow down the download global download
// speed when the queue buffer size is too big.
size_type queue_buffer_size() const;
bool can_write() const;
void get_cache_info(sha1_hash const& ih
, std::vector<cached_piece_info>& ret) const;

View File

@ -215,8 +215,6 @@ namespace libtorrent
void async_check_files(boost::function<void(int, disk_io_job const&)> const& handler);
int queued_bytes() const;
void async_rename_file(int index, std::string const& name
, boost::function<void(int, disk_io_job const&)> const& handler);

View File

@ -321,6 +321,7 @@ namespace libtorrent
, m_queue_buffer_size(0)
, m_last_file_check(time_now_hires())
, m_physical_ram(0)
, m_exceeded_write_queue(false)
, m_ios(ios)
, m_queue_callback(queue_callback)
, m_work(io_service::work(m_ios))
@ -356,6 +357,12 @@ namespace libtorrent
m_jobs.clear();
}
bool disk_io_thread::can_write() const
{
mutex::scoped_lock l(m_queue_mutex);
return !m_exceeded_write_queue;
}
void disk_io_thread::get_cache_info(sha1_hash const& ih, std::vector<cached_piece_info>& ret) const
{
mutex::scoped_lock l(m_piece_mutex);
@ -1623,14 +1630,15 @@ namespace libtorrent
if (m_exceeded_write_queue)
{
int low_watermark = m_settings.max_queued_disk_bytes_low_watermark == 0
? m_settings.max_queued_disk_bytes * 3 / 4
? m_settings.max_queued_disk_bytes / 2
: m_settings.max_queued_disk_bytes_low_watermark;
if (low_watermark >= m_settings.max_queued_disk_bytes)
low_watermark = m_settings.max_queued_disk_bytes * 3 / 4;
low_watermark = m_settings.max_queued_disk_bytes / 2;
if (m_queue_buffer_size < low_watermark
|| m_settings.max_queued_disk_bytes > 0)
|| m_settings.max_queued_disk_bytes == 0)
{
m_exceeded_write_queue = false;
// we just dropped below the high watermark of number of bytes
// queued for writing to the disk. Notify the session so that it
// can trigger all the connections waiting for this event
@ -1734,7 +1742,10 @@ namespace libtorrent
, operation_has_buffer(j) ? j.buffer : 0);
if (post && m_queue_callback)
{
TORRENT_ASSERT(m_exceeded_write_queue == false);
m_ios.post(m_queue_callback);
}
flush_expired_pieces();

View File

@ -2410,7 +2410,7 @@ namespace libtorrent
TORRENT_ASSERT(m_channel_state[download_channel] == peer_info::bw_idle);
m_download_queue.erase(b);
if (t->filesystem().queued_bytes() >= m_ses.settings().max_queued_disk_bytes
if (!m_ses.can_write_to_disk()
&& m_ses.settings().max_queued_disk_bytes
&& t->alerts().should_post<performance_alert>()
&& (now - m_ses.m_last_disk_performance_warning) > seconds(10))
@ -5064,8 +5064,7 @@ namespace libtorrent
if (!bw_limit) return false;
bool disk = m_ses.settings().max_queued_disk_bytes == 0
|| !t || t->get_storage() == 0
|| t->filesystem().queued_bytes() < m_ses.settings().max_queued_disk_bytes
|| m_ses.can_write_to_disk()
// don't block this peer because of disk saturation
// if we're not downloading any pieces from it
|| m_outstanding_bytes == 0;

View File

@ -1626,11 +1626,6 @@ ret:
#endif
}
int piece_manager::queued_bytes() const
{
return m_io_thread.queue_buffer_size();
}
void piece_manager::async_write(
peer_request const& r
, disk_buffer_holder& buffer