diff --git a/include/libtorrent/alloca.hpp b/include/libtorrent/alloca.hpp index 984c773da..b83241e3c 100644 --- a/include/libtorrent/alloca.hpp +++ b/include/libtorrent/alloca.hpp @@ -33,21 +33,28 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_ALLOCA #include "libtorrent/config.hpp" +#include "libtorrent/span.hpp" #if defined TORRENT_WINDOWS || defined TORRENT_MINGW #include -#define TORRENT_ALLOCA(t, n) static_cast(_alloca(sizeof(t) * (n))) +#define TORRENT_ALLOCA(v, t, n) ::libtorrent::span v; { \ + t* TORRENT_ALLOCA_tmp = static_cast(_alloca(sizeof(t) * (n))); \ + v = ::libtorrent::span(TORRENT_ALLOCA_tmp, n); } #elif defined TORRENT_BSD #include -#define TORRENT_ALLOCA(t, n) static_cast(alloca(sizeof(t) * (n))) +#define TORRENT_ALLOCA(v, t, n) ::libtorrent::span v; { \ + t* TORRENT_ALLOCA_tmp = static_cast(alloca(sizeof(t) * (n))); \ + v = ::libtorrent::span(TORRENT_ALLOCA_tmp, n); } #else #include -#define TORRENT_ALLOCA(t, n) static_cast(alloca(sizeof(t) * (n))) +#define TORRENT_ALLOCA(v, t, n) ::libtorrent::span v; { \ + t* TORRENT_ALLOCA_tmp = static_cast(alloca(sizeof(t) * (n))); \ + v = ::libtorrent::span(TORRENT_ALLOCA_tmp, n); } #endif diff --git a/include/libtorrent/disk_buffer_pool.hpp b/include/libtorrent/disk_buffer_pool.hpp index 79dc96a5a..820061dac 100644 --- a/include/libtorrent/disk_buffer_pool.hpp +++ b/include/libtorrent/disk_buffer_pool.hpp @@ -54,6 +54,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/io_service_fwd.hpp" #include "libtorrent/file.hpp" // for iovec_t +#include "libtorrent/span.hpp" namespace libtorrent { @@ -77,7 +78,7 @@ namespace libtorrent char* allocate_buffer(bool& exceeded, std::shared_ptr o , char const* category); void free_buffer(char* buf); - void free_multiple_buffers(char** bufvec, int numbufs); + void free_multiple_buffers(span bufvec); int allocate_iovec(file::iovec_t* iov, int iov_len); void free_iovec(file::iovec_t* iov, int iov_len); diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index 79e515483..d3e31e368 100644 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -149,7 +149,7 @@ namespace libtorrent struct add_torrent_params; TORRENT_EXTRA_EXPORT int copy_bufs(file::iovec_t const* bufs, int bytes, file::iovec_t* target); - TORRENT_EXTRA_EXPORT void advance_bufs(file::iovec_t*& bufs, int bytes); + TORRENT_EXTRA_EXPORT span advance_bufs(span bufs, int bytes); TORRENT_EXTRA_EXPORT void clear_bufs(file::iovec_t const* bufs, int num_bufs); // flags for async_move_storage diff --git a/src/bdecode.cpp b/src/bdecode.cpp index 5b79be6f4..bc91c6e2b 100644 --- a/src/bdecode.cpp +++ b/src/bdecode.cpp @@ -653,7 +653,7 @@ namespace libtorrent // this is the stack of bdecode_token indices, into m_tokens. // sp is the stack pointer, as index into the array, stack int sp = 0; - stack_frame* stack = TORRENT_ALLOCA(stack_frame, depth_limit); + TORRENT_ALLOCA(stack, stack_frame, depth_limit); char const* const orig_start = start; diff --git a/src/block_cache.cpp b/src/block_cache.cpp index 8ea0b853c..00a9adede 100644 --- a/src/block_cache.cpp +++ b/src/block_cache.cpp @@ -569,7 +569,7 @@ void block_cache::try_evict_one_volatile() // some blocks are pinned in this piece, skip it if (pe->pinned > 0) continue; - char** to_delete = TORRENT_ALLOCA(char*, pe->blocks_in_piece); + TORRENT_ALLOCA(to_delete, char*, pe->blocks_in_piece); int num_to_delete = 0; // go through the blocks and evict the ones that are not dirty and not @@ -607,7 +607,7 @@ void block_cache::try_evict_one_volatile() DLOG(stderr, "[%p] removed %d blocks\n", static_cast(this) , num_to_delete); - free_multiple_buffers(to_delete, num_to_delete); + free_multiple_buffers(to_delete.first(num_to_delete)); return; } } @@ -895,7 +895,7 @@ bool block_cache::evict_piece(cached_piece_entry* pe, tailqueue& jo TORRENT_PIECE_ASSERT(pe->in_use, pe); - char** to_delete = TORRENT_ALLOCA(char*, pe->blocks_in_piece); + TORRENT_ALLOCA(to_delete, char*, pe->blocks_in_piece); int num_to_delete = 0; for (int i = 0; i < pe->blocks_in_piece; ++i) { @@ -928,7 +928,7 @@ bool block_cache::evict_piece(cached_piece_entry* pe, tailqueue& jo m_volatile_size -= num_to_delete; } - if (num_to_delete) free_multiple_buffers(to_delete, num_to_delete); + if (num_to_delete) free_multiple_buffers(to_delete.first(num_to_delete)); if (pe->ok_to_evict(true)) { @@ -998,7 +998,7 @@ int block_cache::try_evict_blocks(int num, cached_piece_entry* ignore) DLOG(stderr, "[%p] try_evict_blocks: %d\n", static_cast(this), num); - char** to_delete = TORRENT_ALLOCA(char*, num); + TORRENT_ALLOCA(to_delete, char*, num); int num_to_delete = 0; // There are two ends of the ARC cache we can evict from. There's L1 and L2. @@ -1201,7 +1201,7 @@ int block_cache::try_evict_blocks(int num, cached_piece_entry* ignore) DLOG(stderr, "[%p] removed %d blocks\n", static_cast(this) , num_to_delete); - free_multiple_buffers(to_delete, num_to_delete); + free_multiple_buffers(to_delete.first(num_to_delete)); return num; } @@ -1230,7 +1230,7 @@ void block_cache::clear(tailqueue& jobs) drain_piece_bufs(pe, bufs); } - if (!bufs.empty()) free_multiple_buffers(&bufs[0], int(bufs.size())); + if (!bufs.empty()) free_multiple_buffers(bufs); // clear lru lists for (int i = 0; i < cached_piece_entry::num_lrus; ++i) @@ -1433,7 +1433,7 @@ void block_cache::abort_dirty(cached_piece_entry* pe) TORRENT_PIECE_ASSERT(pe->in_use, pe); - char** to_delete = TORRENT_ALLOCA(char*, pe->blocks_in_piece); + TORRENT_ALLOCA(to_delete, char*, pe->blocks_in_piece); int num_to_delete = 0; for (int i = 0; i < pe->blocks_in_piece; ++i) { @@ -1453,7 +1453,7 @@ void block_cache::abort_dirty(cached_piece_entry* pe) TORRENT_PIECE_ASSERT(pe->num_dirty > 0, pe); --pe->num_dirty; } - if (num_to_delete) free_multiple_buffers(to_delete, num_to_delete); + if (num_to_delete) free_multiple_buffers(to_delete.first(num_to_delete)); update_cache_state(pe); } @@ -1472,7 +1472,7 @@ void block_cache::free_piece(cached_piece_entry* pe) // build a vector of all the buffers we need to free // and free them all in one go - char** to_delete = TORRENT_ALLOCA(char*, pe->blocks_in_piece); + TORRENT_ALLOCA(to_delete, char*, pe->blocks_in_piece); int num_to_delete = 0; int removed_clean = 0; for (int i = 0; i < pe->blocks_in_piece; ++i) @@ -1504,7 +1504,7 @@ void block_cache::free_piece(cached_piece_entry* pe) { m_volatile_size -= num_to_delete; } - if (num_to_delete) free_multiple_buffers(to_delete, num_to_delete); + if (num_to_delete) free_multiple_buffers(to_delete.first(num_to_delete)); update_cache_state(pe); } diff --git a/src/bt_peer_connection.cpp b/src/bt_peer_connection.cpp index c35b3b8af..34b501ba0 100644 --- a/src/bt_peer_connection.cpp +++ b/src/bt_peer_connection.cpp @@ -2153,20 +2153,19 @@ namespace libtorrent const int packet_size = (num_pieces + 7) / 8 + 5; - std::uint8_t* msg = TORRENT_ALLOCA(std::uint8_t, packet_size); - if (msg == nullptr) return; // out of memory - unsigned char* ptr = msg; + TORRENT_ALLOCA(msg, std::uint8_t, packet_size); + if (msg.data() == nullptr) return; // out of memory + auto ptr = msg.begin(); detail::write_int32(packet_size - 4, ptr); detail::write_uint8(msg_bitfield, ptr); if (t->is_seed()) { - std::memset(ptr, 0xff, packet_size - 5); + std::fill_n(ptr, packet_size - 5, 0xff); // Clear trailing bits - unsigned char *p = msg + packet_size - 1; - *p = (0xff << ((8 - (num_pieces & 7)) & 7)) & 0xff; + msg.back() = (0xff << ((8 - (num_pieces & 7)) & 7)) & 0xff; } else { @@ -2206,7 +2205,7 @@ namespace libtorrent #endif m_sent_bitfield = true; - send_buffer(reinterpret_cast(msg), packet_size); + send_buffer(reinterpret_cast(msg.data()), msg.size()); stats_counters().inc_stats_counter(counters::num_outgoing_bitfield); } diff --git a/src/disk_buffer_pool.cpp b/src/disk_buffer_pool.cpp index aa3ba2a30..9f9518335 100644 --- a/src/disk_buffer_pool.cpp +++ b/src/disk_buffer_pool.cpp @@ -340,16 +340,14 @@ namespace libtorrent return ret; } - void disk_buffer_pool::free_multiple_buffers(char** bufvec, int numbufs) + void disk_buffer_pool::free_multiple_buffers(span bufvec) { - char** end = bufvec + numbufs; // sort the pointers in order to maximize cache hits - std::sort(bufvec, end); + std::sort(bufvec.begin(), bufvec.end()); std::unique_lock l(m_pool_mutex); - for (; bufvec != end; ++bufvec) + for (char* buf : bufvec) { - char* buf = *bufvec; TORRENT_ASSERT(is_disk_buffer(buf, l)); free_buffer_impl(buf, l); remove_buffer_in_use(buf); diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 6d9f32cc4..8c5c7078d 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -445,16 +445,16 @@ namespace libtorrent cont_pieces = range_end - range_start; - file::iovec_t* iov = TORRENT_ALLOCA(file::iovec_t, p->blocks_in_piece * cont_pieces); - int* flushing = TORRENT_ALLOCA(int, p->blocks_in_piece * cont_pieces); + TORRENT_ALLOCA(iov, file::iovec_t, p->blocks_in_piece * cont_pieces); + TORRENT_ALLOCA(flushing, int, p->blocks_in_piece * cont_pieces); // this is the offset into iov and flushing for each piece - int* iovec_offset = TORRENT_ALLOCA(int, cont_pieces + 1); + TORRENT_ALLOCA(iovec_offset, int, cont_pieces + 1); int iov_len = 0; // this is the block index each piece starts at int block_start = 0; // keep track of the pieces that have had their refcount incremented // so we know to decrement them later - int* refcount_pieces = TORRENT_ALLOCA(int, cont_pieces); + TORRENT_ALLOCA(refcount_pieces, int, cont_pieces); for (int i = 0; i < cont_pieces; ++i) { cached_piece_entry* pe; @@ -478,7 +478,7 @@ namespace libtorrent ++pe->piece_refcount; iov_len += build_iovec(pe, 0, p->blocks_in_piece - , iov + iov_len, flushing + iov_len, block_start); + , iov.subspan(iov_len).data(), flushing.subspan(iov_len).data(), block_start); block_start += p->blocks_in_piece; } @@ -503,7 +503,7 @@ namespace libtorrent // unlock while we're performing the actual disk I/O // then lock again auto unlock = scoped_unlock(l); - flush_iovec(first_piece, iov, flushing, iov_len, error); + flush_iovec(first_piece, iov.data(), flushing.data(), iov_len, error); } block_start = 0; @@ -526,7 +526,7 @@ namespace libtorrent m_disk_cache.maybe_free_piece(pe); } const int block_diff = iovec_offset[i+1] - iovec_offset[i]; - iovec_flushed(pe, flushing + iovec_offset[i], block_diff + iovec_flushed(pe, flushing.subspan(iovec_offset[i]).data(), block_diff , block_start, error, completed_jobs); block_start += p->blocks_in_piece; } @@ -742,9 +742,9 @@ namespace libtorrent TORRENT_PIECE_ASSERT(start >= 0, pe); TORRENT_PIECE_ASSERT(start < end, pe); - file::iovec_t* iov = TORRENT_ALLOCA(file::iovec_t, pe->blocks_in_piece); - int* flushing = TORRENT_ALLOCA(int, pe->blocks_in_piece); - int iov_len = build_iovec(pe, start, end, iov, flushing, 0); + TORRENT_ALLOCA(iov, file::iovec_t, pe->blocks_in_piece); + TORRENT_ALLOCA(flushing, int, pe->blocks_in_piece); + int iov_len = build_iovec(pe, start, end, iov.data(), flushing.data(), 0); if (iov_len == 0) return 0; TORRENT_PIECE_ASSERT(pe->cache_state <= cached_piece_entry::read_lru1 || pe->cache_state == cached_piece_entry::read_lru2, pe); @@ -757,10 +757,10 @@ namespace libtorrent piece_refcount_holder refcount_holder(pe); auto unlocker = scoped_unlock(l); - flush_iovec(pe, iov, flushing, iov_len, error); + flush_iovec(pe, iov.data(), flushing.data(), iov_len, error); } - iovec_flushed(pe, flushing, iov_len, 0, error, completed_jobs); + iovec_flushed(pe, flushing.data(), iov_len, 0, error, completed_jobs); // if the cache is under high pressure, we need to evict // the blocks we just flushed to make room for more write pieces @@ -979,7 +979,7 @@ namespace libtorrent time_point timeout = min_time(); #endif - cached_piece_entry** to_flush = TORRENT_ALLOCA(cached_piece_entry*, 200); + TORRENT_ALLOCA(to_flush, cached_piece_entry*, 200); int num_flush = 0; for (list_iterator p = m_disk_cache.write_lru_pieces(); p.get(); p.next()) @@ -1235,7 +1235,7 @@ namespace libtorrent int const iov_len = m_disk_cache.pad_job(j, blocks_in_piece , m_settings.get_int(settings_pack::read_cache_line_size)); - file::iovec_t* iov = TORRENT_ALLOCA(file::iovec_t, iov_len); + TORRENT_ALLOCA(iov, file::iovec_t, iov_len); std::unique_lock l(m_cache_mutex); @@ -1253,7 +1253,7 @@ namespace libtorrent l.unlock(); // then we'll actually allocate the buffers - int ret = m_disk_cache.allocate_iovec(iov, iov_len); + int ret = m_disk_cache.allocate_iovec(iov.data(), iov_len); if (ret < 0) { @@ -1283,7 +1283,7 @@ namespace libtorrent , m_settings.get_bool(settings_pack::coalesce_reads)); time_point start_time = clock_type::now(); - ret = j->storage->get_storage_impl()->readv({iov, size_t(iov_len)} + ret = j->storage->get_storage_impl()->readv(iov , j->piece, adjusted_offset, file_flags, j->error); if (!j->error.ec) @@ -1302,7 +1302,7 @@ namespace libtorrent if (ret < 0) { // read failed. free buffers and return error - m_disk_cache.free_iovec(iov, iov_len); + m_disk_cache.free_iovec(iov.data(), iov_len); pe = m_disk_cache.find_piece(j); if (pe == nullptr) @@ -1332,7 +1332,7 @@ namespace libtorrent // as soon we insert the blocks they may be evicted // (if using purgeable memory). In order to prevent that // until we can read from them, increment the refcounts - m_disk_cache.insert_blocks(pe, block, iov, iov_len, j, block_cache::blocks_inc_refcount); + m_disk_cache.insert_blocks(pe, block, iov.data(), iov_len, j, block_cache::blocks_inc_refcount); TORRENT_ASSERT(pe->blocks[block].buf); @@ -2297,8 +2297,8 @@ namespace libtorrent // keep track of which blocks we have locked by incrementing // their refcounts. This is used to decrement only these blocks // later. - int* locked_blocks = TORRENT_ALLOCA(int, blocks_in_piece); - std::memset(locked_blocks, 0, blocks_in_piece * sizeof(int)); + TORRENT_ALLOCA(locked_blocks, int, blocks_in_piece); + std::fill(locked_blocks.begin(), locked_blocks.end(), 0); int num_locked_blocks = 0; // increment the refcounts of all diff --git a/src/file.cpp b/src/file.cpp index 0eabc8669..1c24edbb1 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -173,10 +173,10 @@ namespace int preadv(HANDLE fd, libtorrent::file::iovec_t const* bufs, int num_bufs, std::int64_t file_offset) { - OVERLAPPED* ol = TORRENT_ALLOCA(OVERLAPPED, num_bufs); - std::memset(ol, 0, sizeof(OVERLAPPED) * num_bufs); + TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs); + std::memset(ol.data(), 0, sizeof(OVERLAPPED) * num_bufs); - HANDLE* h = TORRENT_ALLOCA(HANDLE, num_bufs); + TORRENT_ALLOCA(h, HANDLE, num_bufs); for (int i = 0; i < num_bufs; ++i) { @@ -209,7 +209,7 @@ namespace } } - if (wait_for_multiple_objects(num_bufs, h) == WAIT_FAILED) + if (wait_for_multiple_objects(num_bufs, h.data()) == WAIT_FAILED) { ret = -1; goto done; @@ -243,10 +243,10 @@ done: int pwritev(HANDLE fd, libtorrent::file::iovec_t const* bufs, int num_bufs, std::int64_t file_offset) { - OVERLAPPED* ol = TORRENT_ALLOCA(OVERLAPPED, num_bufs); - std::memset(ol, 0, sizeof(OVERLAPPED) * num_bufs); + TORRENT_ALLOCA(ol, OVERLAPPED, num_bufs); + std::memset(ol.data(), 0, sizeof(OVERLAPPED) * num_bufs); - HANDLE* h = TORRENT_ALLOCA(HANDLE, num_bufs); + TORRENT_ALLOCA(h, HANDLE, num_bufs); for (int i = 0; i < num_bufs; ++i) { @@ -279,7 +279,7 @@ done: } } - if (wait_for_multiple_objects(num_bufs, h) == WAIT_FAILED) + if (wait_for_multiple_objects(num_bufs, h.data()) == WAIT_FAILED) { ret = -1; goto done; diff --git a/src/pe_crypto.cpp b/src/pe_crypto.cpp index 6689546c6..311fd02c4 100644 --- a/src/pe_crypto.cpp +++ b/src/pe_crypto.cpp @@ -128,14 +128,14 @@ namespace libtorrent int to_process = m_send_barriers.front().next; - span* bufs; - size_t num_bufs; + span> bufs; bool need_destruct = false; if (to_process != INT_MAX) { - bufs = TORRENT_ALLOCA(span, iovec.size()); + TORRENT_ALLOCA(abufs, span, iovec.size()); + bufs = abufs; need_destruct = true; - num_bufs = 0; + size_t num_bufs = 0; for (int i = 0; to_process > 0 && i < iovec.size(); ++i) { ++num_bufs; @@ -152,19 +152,19 @@ namespace libtorrent to_process -= size; } } + bufs = bufs.first(num_bufs); } else { - bufs = iovec.data(); - num_bufs = iovec.size(); + bufs = iovec; } int next_barrier = 0; span> out_iovec; - if (num_bufs != 0) + if (bufs.size() != 0) { std::tie(next_barrier, out_iovec) - = m_send_barriers.front().enc_handler->encrypt({bufs, size_t(num_bufs)}); + = m_send_barriers.front().enc_handler->encrypt(bufs); } if (m_send_barriers.front().next != INT_MAX) @@ -192,8 +192,8 @@ namespace libtorrent if (next_barrier != INT_MAX && next_barrier != 0) { int payload = 0; - for (int i = 0; i < num_bufs; ++i) - payload += int(bufs[i].size()); + for (auto buf : bufs) + payload += int(buf.size()); int overhead = 0; for (auto buf : out_iovec) @@ -203,8 +203,8 @@ namespace libtorrent #endif if (need_destruct) { - for (int i = 0; i < num_bufs; ++i) - bufs[i].~span(); + for (auto buf : bufs) + buf.~span(); } return std::make_tuple(next_barrier, out_iovec); } diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 55f4f24b2..f4b1821e2 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -5373,18 +5373,18 @@ namespace libtorrent int priority = get_priority(channel); int max_channels = num_classes() + (t ? t->num_classes() : 0) + 2; - bandwidth_channel** channels = TORRENT_ALLOCA(bandwidth_channel*, max_channels); + TORRENT_ALLOCA(channels, bandwidth_channel*, max_channels); // collect the pointers to all bandwidth channels // that apply to this torrent int c = 0; c += m_ses.copy_pertinent_channels(*this, channel - , channels + c, max_channels - c); + , channels.subspan(c).data(), max_channels - c); if (t) { c += m_ses.copy_pertinent_channels(*t, channel - , channels + c, max_channels - c); + , channels.subspan(c).data(), max_channels - c); } #if TORRENT_USE_ASSERTS @@ -5402,7 +5402,7 @@ namespace libtorrent bandwidth_manager* manager = m_ses.get_bandwidth_manager(channel); int ret = manager->request_bandwidth(self() - , bytes, priority, channels, c); + , bytes, priority, channels.data(), c); if (ret == 0) { diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index 2cd428bcf..72fb3d863 100644 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -1275,7 +1275,7 @@ namespace libtorrent // pieces end up changing, instead of making // the piece list dirty, just update those pieces // instead - int* incremented = TORRENT_ALLOCA(int, size); + TORRENT_ALLOCA(incremented, int, size); int num_inc = 0; if (!m_dirty) @@ -1372,7 +1372,7 @@ namespace libtorrent // pieces end up changing, instead of making // the piece list dirty, just update those pieces // instead - int* decremented = TORRENT_ALLOCA(int, size); + TORRENT_ALLOCA(decremented, int, size); int num_dec = 0; if (!m_dirty) @@ -1964,8 +1964,8 @@ namespace libtorrent // lookups when finding a downloading_piece for a specific piece index. // this is important and needs to stay sorted that way, that's why // we're copying it here - downloading_piece const** ordered_partials = TORRENT_ALLOCA( - downloading_piece const*, m_downloads[piece_pos::piece_downloading].size()); + TORRENT_ALLOCA(ordered_partials, downloading_piece const* + , m_downloads[piece_pos::piece_downloading].size()); int num_ordered_partials = 0; // now, copy over the pointers. We also apply a filter here to not @@ -2000,7 +2000,7 @@ namespace libtorrent // chances are that we'll just need a single piece, and once we've // picked from it we're done. Sorting the rest of the list in that // case is a waste of time. - std::sort(ordered_partials, ordered_partials + num_ordered_partials + std::sort(ordered_partials.begin(), ordered_partials.begin() + num_ordered_partials , std::bind(&piece_picker::partial_compare_rarest_first, this , _1, _2)); } @@ -2306,8 +2306,7 @@ get_out: + m_downloads[piece_pos::piece_full].size())); if (partials_size == 0) return ret; - downloading_piece const** partials - = TORRENT_ALLOCA(downloading_piece const*, partials_size); + TORRENT_ALLOCA(partials, downloading_piece const*, partials_size); int c = 0; #if TORRENT_USE_INVARIANT_CHECKS diff --git a/src/storage.cpp b/src/storage.cpp index 7b10cd148..df707d08a 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -134,20 +134,20 @@ namespace libtorrent } } - void advance_bufs(file::iovec_t*& bufs, int bytes) + span advance_bufs(span bufs, int bytes) { int size = 0; for (;;) { - size += int(bufs->iov_len); + size += int(bufs.front().iov_len); if (size >= bytes) { - bufs->iov_base = reinterpret_cast(bufs->iov_base) - + bufs->iov_len - (size - bytes); - bufs->iov_len = size - bytes; - return; + bufs.front().iov_base = reinterpret_cast(bufs.front().iov_base) + + bufs.front().iov_len - (size - bytes); + bufs.front().iov_len = size - bytes; + return bufs; } - ++bufs; + bufs = bufs.subspan(1); } } @@ -1148,11 +1148,11 @@ namespace libtorrent // copy the iovec array so we can use it to keep track of our current // location by updating the head base pointer and size. (see // advance_bufs()) - file::iovec_t* current_buf = TORRENT_ALLOCA(file::iovec_t, num_bufs); - copy_bufs(bufs, size, current_buf); - TORRENT_ASSERT(count_bufs(current_buf, size) == num_bufs); + TORRENT_ALLOCA(current_buf, file::iovec_t, num_bufs); + copy_bufs(bufs, size, current_buf.data()); + TORRENT_ASSERT(count_bufs(current_buf.data(), size) == num_bufs); - file::iovec_t* tmp_buf = TORRENT_ALLOCA(file::iovec_t, num_bufs); + TORRENT_ALLOCA(tmp_buf, file::iovec_t, num_bufs); // the number of bytes left to read in the current file (specified by // file_index). This is the minimum of (file_size - file_offset) and @@ -1184,18 +1184,18 @@ namespace libtorrent // make a copy of the iovec array that _just_ covers the next // file_bytes_left bytes, i.e. just this one operation - copy_bufs(current_buf, file_bytes_left, tmp_buf); + copy_bufs(current_buf.data(), file_bytes_left, tmp_buf.data()); int bytes_transferred = op.file_op(file_index, file_offset, - file_bytes_left, tmp_buf, ec); + file_bytes_left, tmp_buf.data(), ec); if (ec) return -1; // advance our position in the iovec array and the file offset. - advance_bufs(current_buf, bytes_transferred); + current_buf = advance_bufs(current_buf, bytes_transferred); bytes_left -= bytes_transferred; file_offset += bytes_transferred; - TORRENT_ASSERT(count_bufs(current_buf, bytes_left) <= num_bufs); + TORRENT_ASSERT(count_bufs(current_buf.data(), bytes_left) <= num_bufs); // if the file operation returned 0, we've hit end-of-file. We're done if (bytes_transferred == 0) diff --git a/src/torrent.cpp b/src/torrent.cpp index 11bb8da51..9259c137d 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -9604,8 +9604,7 @@ namespace libtorrent // busy blocks we may pick // first, figure out which blocks are eligible for picking // in "busy-mode" - busy_block_t* busy_blocks - = TORRENT_ALLOCA(busy_block_t, blocks_in_piece); + TORRENT_ALLOCA(busy_blocks, busy_block_t, blocks_in_piece); int busy_count = 0; piece_picker::block_info const* info = picker->blocks_for_piece(pi); @@ -9637,16 +9636,18 @@ namespace libtorrent std::printf("\n"); #endif + busy_blocks = busy_blocks.first(busy_count); + // then sort blocks by the number of peers with requests // to the blocks (request the blocks with the fewest peers // first) - std::sort(busy_blocks, busy_blocks + busy_count); + std::sort(busy_blocks.begin(), busy_blocks.end()); // then insert them into the interesting_blocks vector - for (int k = 0; k < busy_count; ++k) + for (auto block : busy_blocks) { interesting_blocks.push_back( - piece_block(piece, busy_blocks[k].index)); + piece_block(piece, block.index)); } } diff --git a/src/utp_stream.cpp b/src/utp_stream.cpp index 37977d017..24581ae79 100644 --- a/src/utp_stream.cpp +++ b/src/utp_stream.cpp @@ -1865,8 +1865,8 @@ bool utp_socket_impl::send_pkt(int const flags) // this alloca() statement won't necessarily produce // correctly aligned memory. That's why we ask for 7 more bytes // and adjust our pointer to be aligned later - p = reinterpret_cast(TORRENT_ALLOCA(char, sizeof(packet) + packet_size - + sizeof(packet*) - 1)); + TORRENT_ALLOCA(ps, char, sizeof(packet) + packet_size + sizeof(packet*) - 1); + p = reinterpret_cast(ps.data()); p = reinterpret_cast(align_pointer(p)); UTP_LOGV("%8p: allocating %d bytes on the stack\n", static_cast(this), packet_size); p->allocated = packet_size; diff --git a/test/test_fast_extension.cpp b/test/test_fast_extension.cpp index 747035477..c61d5f342 100644 --- a/test/test_fast_extension.cpp +++ b/test/test_fast_extension.cpp @@ -221,9 +221,9 @@ void send_bitfield(tcp::socket& s, char const* bits) int num_pieces = int(strlen(bits)); int packet_size = (num_pieces+7)/8 + 5; - char* msg = (char*)TORRENT_ALLOCA(char, packet_size); - memset(msg, 0, packet_size); - char* ptr = msg; + TORRENT_ALLOCA(msg, char, packet_size); + std::fill(msg.begin(), msg.end(), 0); + char* ptr = msg.data(); write_int32(packet_size-4, ptr); write_int8(5, ptr); log("==> bitfield [%s]", bits); @@ -232,7 +232,7 @@ void send_bitfield(tcp::socket& s, char const* bits) ptr[i/8] |= (bits[i] == '1' ? 1 : 0) << i % 8; } error_code ec; - boost::asio::write(s, boost::asio::buffer(msg, packet_size) + boost::asio::write(s, boost::asio::buffer(msg.data(), msg.size()) , boost::asio::transfer_all(), ec); if (ec) TEST_ERROR(ec.message()); } diff --git a/test/test_storage.cpp b/test/test_storage.cpp index 4916f45fa..6d2ce77ef 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -978,21 +978,20 @@ TORRENT_TEST(iovec_advance_bufs) memcpy(iov2, iov1, sizeof(iov1)); - file::iovec_t* iov = iov2; - file::iovec_t* end = iov2 + 10; + span iov = iov2; // advance iov 13 bytes. Make sure what's left fits pattern 1 shifted // 13 bytes - advance_bufs(iov, 13); + iov = advance_bufs(iov, 13); // make sure what's in int counter = 13; - for (int i = 0; i < end - iov; ++i) + for (auto buf : iov) { - unsigned char* buf = (unsigned char*)iov[i].iov_base; - for (int k = 0; k < int(iov[i].iov_len); ++k) + unsigned char* buf_base = (unsigned char*)buf.iov_base; + for (int k = 0; k < int(buf.iov_len); ++k) { - TEST_EQUAL(int(buf[k]), (counter & 0xff)); + TEST_EQUAL(int(buf_base[k]), (counter & 0xff)); ++counter; } }