allow each peer have at least 2 allocated disk blocks at any given time, to avoid stalling when cache_size setting is small. also deprecate use_write_cache

This commit is contained in:
arvidn 2016-03-15 01:55:36 -04:00
parent 6ba5cb7826
commit 08bac479be
6 changed files with 27 additions and 48 deletions

View File

@ -136,11 +136,7 @@ namespace libtorrent
in_progress = 0x20,
// turns into file::coalesce_buffers in the file operation
coalesce_buffers = 0x40,
// the disk cache was enabled when this job was issued, it should use
// the disk cache once it's handled by a disk thread
use_disk_cache = 0x80
coalesce_buffers = 0x40
};
// for write jobs, returns true if its block

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2007-2016, Arvid Norberg
Copyright (c) 2007-2016, Arvid Norberg, Steven Siloti
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -259,14 +259,16 @@ namespace libtorrent
// passes the hash check, it is taken out of parole mode.
use_parole_mode,
// enable and disable caching of read blocks and blocks to be written
// to disk respsectively. the purpose of the read cache is partly
// read-ahead of requests but also to avoid reading blocks back from
// the disk multiple times for popular pieces. the write cache purpose
// is to hold off writing blocks to disk until they have been hashed,
// to avoid having to read them back in again.
// enable and disable caching of blocks read from disk. the purpose of
// the read cache is partly read-ahead of requests but also to avoid
// reading blocks back from the disk multiple times for popular
// pieces.
use_read_cache,
#ifndef TORRENT_NO_DEPRECATED
use_write_cache,
#else
deprecated7,
#endif
// this will make the disk cache never flush a write piece if it would
// cause is to have to re-read it once we want to calculate the piece

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2007-2016, Arvid Norberg
Copyright (c) 2007-2016, Arvid Norberg, Steven Siloti
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -1208,14 +1208,6 @@ namespace libtorrent
int disk_io_thread::do_read(disk_io_job* j, jobqueue_t& completed_jobs)
{
if ((j->flags & disk_io_job::use_disk_cache) == 0)
{
// we're not using a cache. This is the simple path
// just read straight from the file
int ret = do_uncached_read(j);
return ret;
}
int block_size = m_disk_cache.block_size();
int piece_size = j->storage->files()->piece_size(j->piece);
int blocks_in_piece = (piece_size + block_size - 1) / block_size;
@ -1232,26 +1224,8 @@ namespace libtorrent
cached_piece_entry* pe = m_disk_cache.find_piece(j);
if (pe == NULL)
{
// this isn't supposed to happen. The piece is supposed
// to be allocated when the read job is posted to the
// queue, and have 'outstanding_read' set to 1
TORRENT_ASSERT(false);
int cache_state = (j->flags & disk_io_job::volatile_read)
? cached_piece_entry::volatile_read_lru
: cached_piece_entry::read_lru1;
pe = m_disk_cache.allocate_piece(j, cache_state);
if (pe == NULL)
{
j->error.ec = error::no_memory;
j->error.operation = storage_error::alloc_cache_piece;
m_disk_cache.free_iovec(iov, iov_len);
return -1;
}
#if TORRENT_USE_ASSERTS
pe->piece_log.push_back(piece_log_t(piece_log_t::set_outstanding_jobs));
#endif
pe->outstanding_read = 1;
l.unlock();
return do_uncached_read(j);
}
TORRENT_PIECE_ASSERT(pe->outstanding_read == 1, pe);
@ -1633,7 +1607,6 @@ namespace libtorrent
j->error.operation = storage_error::read;
return 0;
}
j->flags |= disk_io_job::use_disk_cache;
if (pe->outstanding_read)
{
TORRENT_PIECE_ASSERT(j->piece == pe->piece, pe);

View File

@ -2611,7 +2611,13 @@ namespace libtorrent
return;
}
if (exceeded)
// every peer is entitled to have two disk blocks allocated at any given
// time, regardless of whether the cache size is exceeded or not. If this
// was not the case, when the cache size setting is very small, most peers
// would be blocked most of the time, because the disk cache would
// continously be in exceeded state. Only rarely would it actually drop
// down to 0 and unblock all peers.
if (exceeded && m_outstanding_writing_bytes > 0)
{
if ((m_channel_state[download_channel] & peer_info::bw_disk) == 0)
m_counters.inc_stats_counter(counters::num_peers_down_disk);
@ -4541,7 +4547,9 @@ namespace libtorrent
return false;
}
if (exceeded)
// to understand why m_outstanding_writing_bytes is here, see comment by
// the other call to allocate_disk_buffer()
if (exceeded && m_outstanding_writing_bytes > 0)
{
#ifndef TORRENT_DISABLE_LOGGING
peer_log(peer_log_alert::info, "DISK", "exceeded disk buffer watermark");

View File

@ -150,7 +150,7 @@ namespace libtorrent
SET(upnp_ignore_nonrouters, false, 0),
SET(use_parole_mode, true, 0),
SET(use_read_cache, true, 0),
SET(use_write_cache, true, 0),
DEPRECATED_SET(use_write_cache, true, 0),
SET(dont_flush_write_cache, false, 0),
SET(explicit_read_cache, false, 0),
SET(coalesce_reads, false, 0),
@ -603,14 +603,14 @@ namespace libtorrent
&& std::find(callbacks.begin(), callbacks.end(), sa.fun) == callbacks.end())
callbacks.push_back(sa.fun);
}
for (std::vector<std::pair<boost::uint16_t, int> >::const_iterator i = pack->m_ints.begin()
, end(pack->m_ints.end()); i != end; ++i)
{
// disregard setting indices that are not int types
if ((i->first & settings_pack::type_mask) != settings_pack::int_type_base)
continue;
// ignore settings that are out of bounds
int index = i->first & settings_pack::index_mask;
if (index < 0 || index >= settings_pack::num_int_settings)
@ -629,7 +629,7 @@ namespace libtorrent
// disregard setting indices that are not bool types
if ((i->first & settings_pack::type_mask) != settings_pack::bool_type_base)
continue;
// ignore settings that are out of bounds
int index = i->first & settings_pack::index_mask;
if (index < 0 || index >= settings_pack::num_bool_settings)