separate alignment requirements for file offset and buffer address

This commit is contained in:
Arvid Norberg 2009-01-19 09:21:21 +00:00
parent d506bcd5de
commit cedea0980f
2 changed files with 25 additions and 11 deletions

View File

@ -135,9 +135,13 @@ namespace libtorrent
// when opened in unbuffered mode, this is the // when opened in unbuffered mode, this is the
// required alignment of file_offsets. i.e. // required alignment of file_offsets. i.e.
// any (file_offset & (pos_alignment()-1)) == 0 // any (file_offset & (pos_alignment()-1)) == 0
// is a precondition // is a precondition to read and write operations
int pos_alignment() const; int pos_alignment() const;
// when opened in unbuffered mode, this is the
// required alignment of buffer addresses
int buf_alignment() const;
size_type writev(size_type file_offset, iovec_t const* bufs, int num_bufs, error_code& ec); size_type writev(size_type file_offset, iovec_t const* bufs, int num_bufs, error_code& ec);
size_type readv(size_type file_offset, iovec_t const* bufs, int num_bufs, error_code& ec); size_type readv(size_type file_offset, iovec_t const* bufs, int num_bufs, error_code& ec);

View File

@ -270,6 +270,16 @@ namespace libtorrent
#endif #endif
} }
int file::buf_alignment() const
{
#if defined TORRENT_WINDOWS
init_file();
return m_page_size;
#else
return pos_alignment();
#endif
}
void file::close() void file::close()
{ {
#if defined TORRENT_WINDOWS || defined TORRENT_LINUX #if defined TORRENT_WINDOWS || defined TORRENT_LINUX
@ -333,11 +343,11 @@ namespace libtorrent
TORRENT_ASSERT((file_offset & (pos_alignment()-1)) == 0); TORRENT_ASSERT((file_offset & (pos_alignment()-1)) == 0);
for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i)
{ {
TORRENT_ASSERT((int(i->iov_base) & (m_page_size-1)) == 0); TORRENT_ASSERT((int(i->iov_base) & (buf_alignment()-1)) == 0);
// every buffer must be a multiple of the page size // every buffer must be a multiple of the page size
// except for the last one // except for the last one
TORRENT_ASSERT((i->iov_len & (m_page_size-1)) == 0 || i == end-1); TORRENT_ASSERT((i->iov_len & (pos_alignment()-1)) == 0 || i == end-1);
if ((i->iov_len & (m_page_size-1)) != 0) eof = true; if ((i->iov_len & (pos_alignment()-1)) != 0) eof = true;
size += i->iov_len; size += i->iov_len;
} }
error_code code; error_code code;
@ -442,7 +452,7 @@ namespace libtorrent
if (!aligned) if (!aligned)
{ {
size = bufs_size(bufs, num_bufs); size = bufs_size(bufs, num_bufs);
if (size & (m_page_size-1) == 0) aligned = true; if (size & (pos_alignment()-1) == 0) aligned = true;
} }
if (aligned) if (aligned)
#endif #endif
@ -459,7 +469,7 @@ namespace libtorrent
file::iovec_t* temp_bufs = TORRENT_ALLOCA(file::iovec_t, num_bufs); file::iovec_t* temp_bufs = TORRENT_ALLOCA(file::iovec_t, num_bufs);
memcpy(temp_bufs, bufs, sizeof(file::iovec_t) * num_bufs); memcpy(temp_bufs, bufs, sizeof(file::iovec_t) * num_bufs);
iovec_t& last = temp_bufs[num_bufs-1]; iovec_t& last = temp_bufs[num_bufs-1];
last.iov_len = (last.iov_len & ~(m_page_size-1)) + m_page_size; last.iov_len = (last.iov_len & ~(pos_alignment()-1)) + m_page_size;
ret = ::readv(m_fd, temp_bufs, num_bufs); ret = ::readv(m_fd, temp_bufs, num_bufs);
if (ret < 0) if (ret < 0)
{ {
@ -493,11 +503,11 @@ namespace libtorrent
TORRENT_ASSERT((file_offset & (pos_alignment()-1)) == 0); TORRENT_ASSERT((file_offset & (pos_alignment()-1)) == 0);
for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i)
{ {
TORRENT_ASSERT((int(i->iov_base) & (m_page_size-1)) == 0); TORRENT_ASSERT((int(i->iov_base) & (buf_alignment()-1)) == 0);
// every buffer must be a multiple of the page size // every buffer must be a multiple of the page size
// except for the last one // except for the last one
TORRENT_ASSERT((i->iov_len & (m_page_size-1)) == 0 || i == end-1); TORRENT_ASSERT((i->iov_len & (pos_alignment()-1)) == 0 || i == end-1);
if ((i->iov_len & (m_page_size-1)) != 0) eof = true; if ((i->iov_len & (pos_alignment()-1)) != 0) eof = true;
size += i->iov_len; size += i->iov_len;
} }
error_code code; error_code code;
@ -646,7 +656,7 @@ namespace libtorrent
if (!aligned) if (!aligned)
{ {
size = bufs_size(bufs, num_bufs); size = bufs_size(bufs, num_bufs);
if (size & (m_page_size-1) == 0) aligned = true; if (size & (pos_alignment()-1) == 0) aligned = true;
} }
if (aligned) if (aligned)
#endif #endif
@ -663,7 +673,7 @@ namespace libtorrent
file::iovec_t* temp_bufs = TORRENT_ALLOCA(file::iovec_t, num_bufs); file::iovec_t* temp_bufs = TORRENT_ALLOCA(file::iovec_t, num_bufs);
memcpy(temp_bufs, bufs, sizeof(file::iovec_t) * num_bufs); memcpy(temp_bufs, bufs, sizeof(file::iovec_t) * num_bufs);
iovec_t& last = temp_bufs[num_bufs-1]; iovec_t& last = temp_bufs[num_bufs-1];
last.iov_len = (last.iov_len & ~(m_page_size-1)) + m_page_size; last.iov_len = (last.iov_len & ~(pos_alignment()-1)) + pos_alignment();
ret = ::writev(m_fd, temp_bufs, num_bufs); ret = ::writev(m_fd, temp_bufs, num_bufs);
if (ret < 0) if (ret < 0)
{ {