some optimizations (#858)

allow disk I/O callback objects to be moved into disk io jobs
This commit is contained in:
Arvid Norberg 2016-06-27 01:02:00 -04:00 committed by GitHub
parent 7476af0c97
commit 31b2a03005
6 changed files with 79 additions and 82 deletions

View File

@ -53,50 +53,50 @@ namespace libtorrent
struct TORRENT_EXTRA_EXPORT disk_interface
{
virtual void async_read(piece_manager* storage, peer_request const& r
, boost::function<void(disk_io_job const*)> const& handler, void* requester
, boost::function<void(disk_io_job const*)> handler, void* requester
, int flags = 0) = 0;
virtual void async_write(piece_manager* storage, peer_request const& r
, disk_buffer_holder buffer
, boost::function<void(disk_io_job const*)> const& handler
, boost::function<void(disk_io_job const*)> handler
, int flags = 0) = 0;
virtual void async_hash(piece_manager* storage, int piece, int flags
, boost::function<void(disk_io_job const*)> const& handler, void* requester) = 0;
, boost::function<void(disk_io_job const*)> handler, void* requester) = 0;
virtual void async_move_storage(piece_manager* storage, std::string const& p, int flags
, boost::function<void(disk_io_job const*)> const& handler) = 0;
, boost::function<void(disk_io_job const*)> handler) = 0;
virtual void async_release_files(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler
, boost::function<void(disk_io_job const*)> handler
= boost::function<void(disk_io_job const*)>()) = 0;
virtual void async_check_files(piece_manager* storage
, add_torrent_params const* resume_data
, std::vector<std::string>& links
, boost::function<void(disk_io_job const*)> const& handler) = 0;
, boost::function<void(disk_io_job const*)> handler) = 0;
#ifndef TORRENT_NO_DEPRECATE
virtual void async_cache_piece(piece_manager* storage, int piece
, boost::function<void(disk_io_job const*)> const& handler) = 0;
, boost::function<void(disk_io_job const*)> handler) = 0;
virtual void async_finalize_file(piece_manager*, int file
, boost::function<void(disk_io_job const*)> const& handler
, boost::function<void(disk_io_job const*)> handler
= boost::function<void(disk_io_job const*)>()) = 0;
#endif
virtual void async_flush_piece(piece_manager* storage, int piece
, boost::function<void(disk_io_job const*)> const& handler
, boost::function<void(disk_io_job const*)> handler
= boost::function<void(disk_io_job const*)>()) = 0;
virtual void async_stop_torrent(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler)= 0;
, boost::function<void(disk_io_job const*)> handler)= 0;
virtual void async_rename_file(piece_manager* storage, int index, std::string const& name
, boost::function<void(disk_io_job const*)> const& handler) = 0;
, boost::function<void(disk_io_job const*)> handler) = 0;
virtual void async_delete_files(piece_manager* storage, int options
, boost::function<void(disk_io_job const*)> const& handler) = 0;
, boost::function<void(disk_io_job const*)> handler) = 0;
virtual void async_set_file_priority(piece_manager* storage
, std::vector<std::uint8_t> const& prio
, boost::function<void(disk_io_job const*)> const& handler) = 0;
, boost::function<void(disk_io_job const*)> handler) = 0;
virtual void async_load_torrent(add_torrent_params* params
, boost::function<void(disk_io_job const*)> const& handler) = 0;
, boost::function<void(disk_io_job const*)> handler) = 0;
virtual void async_tick_torrent(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler) = 0;
, boost::function<void(disk_io_job const*)> handler) = 0;
virtual void clear_read_cache(piece_manager* storage) = 0;
virtual void async_clear_piece(piece_manager* storage, int index
, boost::function<void(disk_io_job const*)> const& handler) = 0;
, boost::function<void(disk_io_job const*)> handler) = 0;
virtual void clear_piece(piece_manager* storage, int index) = 0;
virtual void update_stats_counters(counters& c) const = 0;

View File

@ -300,50 +300,50 @@ namespace libtorrent
void abort(bool wait);
void async_read(piece_manager* storage, peer_request const& r
, boost::function<void(disk_io_job const*)> const& handler, void* requester
, boost::function<void(disk_io_job const*)> handler, void* requester
, int flags = 0) override;
void async_write(piece_manager* storage, peer_request const& r
, disk_buffer_holder buffer
, boost::function<void(disk_io_job const*)> const& handler
, boost::function<void(disk_io_job const*)> handler
, int flags = 0) override;
void async_hash(piece_manager* storage, int piece, int flags
, boost::function<void(disk_io_job const*)> const& handler, void* requester) override;
, boost::function<void(disk_io_job const*)> handler, void* requester) override;
void async_move_storage(piece_manager* storage, std::string const& p, int flags
, boost::function<void(disk_io_job const*)> const& handler) override;
, boost::function<void(disk_io_job const*)> handler) override;
void async_release_files(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler
, boost::function<void(disk_io_job const*)> handler
= boost::function<void(disk_io_job const*)>()) override;
void async_delete_files(piece_manager* storage, int options
, boost::function<void(disk_io_job const*)> const& handler) override;
, boost::function<void(disk_io_job const*)> handler) override;
void async_check_files(piece_manager* storage
, add_torrent_params const* resume_data
, std::vector<std::string>& links
, boost::function<void(disk_io_job const*)> const& handler) override;
, boost::function<void(disk_io_job const*)> handler) override;
void async_rename_file(piece_manager* storage, int index, std::string const& name
, boost::function<void(disk_io_job const*)> const& handler) override;
, boost::function<void(disk_io_job const*)> handler) override;
void async_stop_torrent(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler) override;
, boost::function<void(disk_io_job const*)> handler) override;
#ifndef TORRENT_NO_DEPRECATE
void async_cache_piece(piece_manager* storage, int piece
, boost::function<void(disk_io_job const*)> const& handler) override;
, boost::function<void(disk_io_job const*)> handler) override;
void async_finalize_file(piece_manager* storage, int file
, boost::function<void(disk_io_job const*)> const& handler
, boost::function<void(disk_io_job const*)> handler
= boost::function<void(disk_io_job const*)>()) override;
#endif
void async_flush_piece(piece_manager* storage, int piece
, boost::function<void(disk_io_job const*)> const& handler
, boost::function<void(disk_io_job const*)> handler
= boost::function<void(disk_io_job const*)>()) override;
void async_set_file_priority(piece_manager* storage
, std::vector<std::uint8_t> const& prio
, boost::function<void(disk_io_job const*)> const& handler) override;
, boost::function<void(disk_io_job const*)> handler) override;
void async_load_torrent(add_torrent_params* params
, boost::function<void(disk_io_job const*)> const& handler) override;
, boost::function<void(disk_io_job const*)> handler) override;
void async_tick_torrent(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler) override;
, boost::function<void(disk_io_job const*)> handler) override;
void clear_read_cache(piece_manager* storage) override;
void async_clear_piece(piece_manager* storage, int index
, boost::function<void(disk_io_job const*)> const& handler) override;
, boost::function<void(disk_io_job const*)> handler) override;
// this is not asynchronous and requires that the piece does not
// have any pending buffers. It's meant to be used for pieces that
// were just read and hashed and failed the hash check.

View File

@ -1479,7 +1479,7 @@ namespace libtorrent
}
void disk_io_thread::async_read(piece_manager* storage, peer_request const& r
, boost::function<void(disk_io_job const*)> const& handler, void* requester
, boost::function<void(disk_io_job const*)> handler, void* requester
, int flags)
{
INVARIANT_CHECK;
@ -1503,7 +1503,7 @@ namespace libtorrent
j->buffer.disk_block = 0;
j->flags = flags;
j->requester = requester;
j->callback = handler;
j->callback = std::move(handler);
std::unique_lock<std::mutex> l(m_cache_mutex);
int ret = prep_read_job_impl(j);
@ -1512,7 +1512,7 @@ namespace libtorrent
switch (ret)
{
case 0:
if (handler) handler(j);
if (j->callback) j->callback(j);
free_job(j);
break;
case 1:
@ -1599,7 +1599,7 @@ namespace libtorrent
void disk_io_thread::async_write(piece_manager* storage, peer_request const& r
, disk_buffer_holder buffer
, boost::function<void(disk_io_job const*)> const& handler
, boost::function<void(disk_io_job const*)> handler
, int flags)
{
INVARIANT_CHECK;
@ -1619,7 +1619,7 @@ namespace libtorrent
j->d.io.offset = r.start;
j->d.io.buffer_size = r.length;
j->buffer.disk_block = buffer.get();
j->callback = handler;
j->callback = std::move(handler);
j->flags = flags;
#if TORRENT_USE_ASSERTS
@ -1709,7 +1709,7 @@ namespace libtorrent
}
void disk_io_thread::async_hash(piece_manager* storage, int piece, int flags
, boost::function<void(disk_io_job const*)> const& handler, void* requester)
, boost::function<void(disk_io_job const*)> handler, void* requester)
{
#ifdef TORRENT_DEBUG
// the caller must increment the torrent refcount before
@ -1720,7 +1720,7 @@ namespace libtorrent
disk_io_job* j = allocate_job(disk_io_job::hash);
j->storage = storage->shared_from_this();
j->piece = piece;
j->callback = handler;
j->callback = std::move(handler);
j->flags = flags;
j->requester = requester;
@ -1745,7 +1745,7 @@ namespace libtorrent
#endif
l.unlock();
if (handler) handler(j);
if (j->callback) j->callback(j);
free_job(j);
return;
}
@ -1754,7 +1754,7 @@ namespace libtorrent
}
void disk_io_thread::async_move_storage(piece_manager* storage, std::string const& p, int flags
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
#ifdef TORRENT_DEBUG
// the caller must increment the torrent refcount before
@ -1765,25 +1765,25 @@ namespace libtorrent
disk_io_job* j = allocate_job(disk_io_job::move_storage);
j->storage = storage->shared_from_this();
j->buffer.string = allocate_string_copy(p.c_str());
j->callback = handler;
j->callback = std::move(handler);
j->flags = flags;
add_fence_job(storage, j);
}
void disk_io_thread::async_release_files(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
disk_io_job* j = allocate_job(disk_io_job::release_files);
j->storage = storage->shared_from_this();
j->callback = handler;
j->callback = std::move(handler);
add_fence_job(storage, j);
}
void disk_io_thread::async_delete_files(piece_manager* storage
, int const options
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
#ifdef TORRENT_DEBUG
// the caller must increment the torrent refcount before
@ -1822,7 +1822,7 @@ namespace libtorrent
disk_io_job* j = allocate_job(disk_io_job::delete_files);
j->storage = storage->shared_from_this();
j->callback = handler;
j->callback = std::move(handler);
j->buffer.delete_options = options;
add_fence_job(storage, j);
@ -1836,7 +1836,7 @@ namespace libtorrent
void disk_io_thread::async_check_files(piece_manager* storage
, add_torrent_params const* resume_data
, std::vector<std::string>& links
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
#ifdef TORRENT_DEBUG
// the caller must increment the torrent refcount before
@ -1852,13 +1852,13 @@ namespace libtorrent
j->storage = storage->shared_from_this();
j->buffer.check_resume_data = resume_data;
j->d.links = links_vector;
j->callback = handler;
j->callback = std::move(handler);
add_fence_job(storage, j);
}
void disk_io_thread::async_rename_file(piece_manager* storage, int index, std::string const& name
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
#ifdef TORRENT_DEBUG
// the caller must increment the torrent refcount before
@ -1870,12 +1870,12 @@ namespace libtorrent
j->storage = storage->shared_from_this();
j->piece = index;
j->buffer.string = allocate_string_copy(name.c_str());
j->callback = handler;
j->callback = std::move(handler);
add_fence_job(storage, j);
}
void disk_io_thread::async_stop_torrent(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
// remove outstanding hash jobs belonging to this torrent
std::unique_lock<std::mutex> l2(m_job_mutex);
@ -1899,7 +1899,7 @@ namespace libtorrent
disk_io_job* j = allocate_job(disk_io_job::stop_torrent);
j->storage = storage->shared_from_this();
j->callback = handler;
j->callback = std::move(handler);
add_fence_job(storage, j);
jobqueue_t completed_jobs;
@ -1911,7 +1911,7 @@ namespace libtorrent
#ifndef TORRENT_NO_DEPRECATE
void disk_io_thread::async_cache_piece(piece_manager* storage, int piece
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
#ifdef TORRENT_DEBUG
// the caller must increment the torrent refcount before
@ -1922,13 +1922,13 @@ namespace libtorrent
disk_io_job* j = allocate_job(disk_io_job::cache_piece);
j->storage = storage->shared_from_this();
j->piece = piece;
j->callback = handler;
j->callback = std::move(handler);
add_job(j);
}
void disk_io_thread::async_finalize_file(piece_manager* storage, int file
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
#ifdef TORRENT_DEBUG
// the caller must increment the torrent refcount before
@ -1939,14 +1939,14 @@ namespace libtorrent
disk_io_job* j = allocate_job(disk_io_job::finalize_file);
j->storage = storage->shared_from_this();
j->piece = file;
j->callback = handler;
j->callback = std::move(handler);
add_job(j);
}
#endif // TORRENT_NO_DEPRECATE
void disk_io_thread::async_flush_piece(piece_manager* storage, int piece
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
#ifdef TORRENT_DEBUG
// the caller must increment the torrent refcount before
@ -1957,12 +1957,12 @@ namespace libtorrent
disk_io_job* j = allocate_job(disk_io_job::flush_piece);
j->storage = storage->shared_from_this();
j->piece = piece;
j->callback = handler;
j->callback = std::move(handler);
if (m_abort)
{
j->error.ec = boost::asio::error::operation_aborted;
if (handler) handler(j);
if (j->callback) j->callback(j);
free_job(j);
return;
}
@ -1972,7 +1972,7 @@ namespace libtorrent
void disk_io_thread::async_set_file_priority(piece_manager* storage
, std::vector<std::uint8_t> const& prios
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
#ifdef TORRENT_DEBUG
// the caller must increment the torrent refcount before
@ -1985,27 +1985,27 @@ namespace libtorrent
disk_io_job* j = allocate_job(disk_io_job::file_priority);
j->storage = storage->shared_from_this();
j->buffer.priorities = p;
j->callback = handler;
j->callback = std::move(handler);
add_fence_job(storage, j);
}
void disk_io_thread::async_load_torrent(add_torrent_params* params
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
disk_io_job* j = allocate_job(disk_io_job::load_torrent);
j->requester = reinterpret_cast<char*>(params);
j->callback = handler;
j->callback = std::move(handler);
add_job(j);
}
void disk_io_thread::async_tick_torrent(piece_manager* storage
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
disk_io_job* j = allocate_job(disk_io_job::tick_storage);
j->storage = storage->shared_from_this();
j->callback = handler;
j->callback = std::move(handler);
add_job(j);
}
@ -2028,7 +2028,7 @@ namespace libtorrent
}
void disk_io_thread::async_clear_piece(piece_manager* storage, int index
, boost::function<void(disk_io_job const*)> const& handler)
, boost::function<void(disk_io_job const*)> handler)
{
#ifdef TORRENT_DEBUG
// the caller must increment the torrent refcount before
@ -2039,7 +2039,7 @@ namespace libtorrent
disk_io_job* j = allocate_job(disk_io_job::clear_piece);
j->storage = storage->shared_from_this();
j->piece = index;
j->callback = handler;
j->callback = std::move(handler);
// regular jobs are not guaranteed to be executed in-order
// since clear piece must guarantee that all write jobs that

View File

@ -2725,7 +2725,7 @@ namespace libtorrent
return;
}
time_point now = clock_type::now();
time_point const now = clock_type::now();
t->need_picker();
@ -2824,7 +2824,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_LOGGING
t->debug_log("PIECE [%p] (%d ms) (%d)", static_cast<void*>(this)
, int(total_milliseconds(clock_type::now() - m_unchoke_time)), t->num_have());
, int(total_milliseconds(now - m_unchoke_time)), t->num_have());
peer_log(peer_log_alert::info, "FILE_ASYNC_WRITE", "piece: %d s: %x l: %x"
, p.piece, p.start, p.length);
@ -2872,9 +2872,9 @@ namespace libtorrent
if (!m_download_queue.empty())
m_requested = now;
bool was_finished = picker.is_piece_finished(p.piece);
bool const was_finished = picker.is_piece_finished(p.piece);
// did we request this block from any other peers?
bool multi = picker.num_peers(block_finished) > 1;
bool const multi = picker.num_peers(block_finished) > 1;
// std::fprintf(stderr, "peer_connection mark_as_writing peer: %p piece: %d block: %d\n"
// , peer_info_struct(), block_finished.piece_index, block_finished.block_index);
picker.mark_as_writing(block_finished, peer_info_struct());
@ -3301,7 +3301,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_LOGGING
{
time_point now = clock_type::now();
time_point const now = clock_type::now();
t->debug_log("ALLOW FAST [%p] (%d ms)"
, static_cast<void*>(this)
, int(total_milliseconds(now - m_connect_time)));
@ -3983,8 +3983,7 @@ namespace libtorrent
// request timeout.
m_requested = aux::time_now();
#ifndef TORRENT_DISABLE_LOGGING
t->debug_log("REQUEST [%p] (%d ms)", static_cast<void*>(this)
, int(total_milliseconds(clock_type::now() - m_unchoke_time)));
t->debug_log("REQUEST [%p]", static_cast<void*>(this));
#endif
}
}

View File

@ -2089,7 +2089,7 @@ namespace libtorrent
{
for (int i = m_reverse_cursor - 1; i >= m_cursor; --i)
{
pc.inc_stats_counter(counters::piece_picker_sequential_loops);
// pc.inc_stats_counter(counters::piece_picker_sequential_loops);
if (!is_piece_free(i, pieces)) continue;
// we've already added high priority pieces
if (piece_priority(i) == priority_levels - 1) continue;
@ -2108,7 +2108,7 @@ namespace libtorrent
{
for (int i = m_cursor; i < m_reverse_cursor; ++i)
{
pc.inc_stats_counter(counters::piece_picker_sequential_loops);
// pc.inc_stats_counter(counters::piece_picker_sequential_loops);
if (!is_piece_free(i, pieces)) continue;
// we've already added high priority pieces
if (piece_priority(i) == priority_levels - 1) continue;

View File

@ -80,12 +80,10 @@ namespace libtorrent
bool time_critical_mode = t.num_time_critical_pieces() > 0;
int desired_queue_size = c.desired_queue_size();
// in time critical mode, only have 1 outstanding request at a time
// via normal requests
if (time_critical_mode)
desired_queue_size = (std::min)(1, desired_queue_size);
int const desired_queue_size = time_critical_mode
? 1 : c.desired_queue_size();
int num_requests = desired_queue_size
- int(c.download_queue().size())
@ -95,9 +93,9 @@ namespace libtorrent
c.peer_log(peer_log_alert::info, "PIECE_PICKER"
, "dlq: %d rqq: %d target: %d req: %d engame: %d"
, int(c.download_queue().size()), int(c.request_queue().size())
, c.desired_queue_size(), num_requests, c.endgame());
, desired_queue_size, num_requests, c.endgame());
#endif
TORRENT_ASSERT(c.desired_queue_size() > 0);
TORRENT_ASSERT(desired_queue_size > 0);
// if our request queue is already full, we
// don't have to make any new requests yet
if (num_requests <= 0) return false;