forked from premiere/premiere-libtorrent
refactor for separation of clz software/hardware based (#985)
refactor for separation of clz software/hardware based
This commit is contained in:
parent
1bae47479b
commit
7ea9e76b37
|
@ -114,6 +114,7 @@ set(sources
|
|||
ConvertUTF
|
||||
xml_parse
|
||||
version
|
||||
ffs
|
||||
|
||||
# -- extensions --
|
||||
ut_pex
|
||||
|
|
1
Jamfile
1
Jamfile
|
@ -679,6 +679,7 @@ SOURCES =
|
|||
session_settings
|
||||
proxy_settings
|
||||
file_progress
|
||||
ffs
|
||||
|
||||
# -- extensions --
|
||||
ut_pex
|
||||
|
|
|
@ -171,6 +171,7 @@ nobase_include_HEADERS = \
|
|||
aux_/openssl.hpp \
|
||||
aux_/byteswap.hpp \
|
||||
aux_/cppint_import_export.hpp \
|
||||
aux_/ffs.hpp \
|
||||
\
|
||||
extensions/smart_ban.hpp \
|
||||
extensions/ut_metadata.hpp \
|
||||
|
|
|
@ -45,4 +45,3 @@ namespace libtorrent { namespace aux
|
|||
} }
|
||||
|
||||
#endif // TORRENT_CPUID_HPP_INCLUDED
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2014-2016, Arvid Norberg, Alden Torres
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_FFS_HPP_INCLUDE
|
||||
#define TORRENT_FFS_HPP_INCLUDE
|
||||
|
||||
#include <cstdint>
|
||||
#include "libtorrent/export.hpp"
|
||||
#include "libtorrent/span.hpp"
|
||||
|
||||
namespace libtorrent { namespace aux
|
||||
{
|
||||
// these functions expect the range to be in big-endian byte order
|
||||
TORRENT_EXTRA_EXPORT int clz_sw(span<std::uint32_t const> buf);
|
||||
// if this function is called in an unsupported platform, returns -1
|
||||
// consider call always clz(buf)
|
||||
TORRENT_EXTRA_EXPORT int clz_hw(span<std::uint32_t const> buf);
|
||||
|
||||
// this function statically determines if hardware or software is used
|
||||
// and expect the range to be in big-endian byte order
|
||||
TORRENT_EXTRA_EXPORT int clz(span<std::uint32_t const> buf);
|
||||
}}
|
||||
|
||||
#endif // TORRENT_FFS_HPP_INCLUDE
|
|
@ -41,19 +41,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "libtorrent/aux_/byteswap.hpp"
|
||||
#include "libtorrent/aux_/ffs.hpp"
|
||||
|
||||
#if TORRENT_USE_IOSTREAM
|
||||
#include <iosfwd>
|
||||
#endif // TORRENT_USE_IOSTREAM
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
|
@ -80,7 +73,7 @@ namespace libtorrent
|
|||
static sha1_hash max()
|
||||
{
|
||||
sha1_hash ret;
|
||||
memset(ret.m_number, 0xff, size());
|
||||
std::memset(ret.m_number, 0xff, size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -90,7 +83,7 @@ namespace libtorrent
|
|||
static sha1_hash min()
|
||||
{
|
||||
sha1_hash ret;
|
||||
memset(ret.m_number, 0, size());
|
||||
std::memset(ret.m_number, 0, size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -137,11 +130,11 @@ namespace libtorrent
|
|||
// standard comparison operators
|
||||
bool operator==(sha1_hash const& n) const
|
||||
{
|
||||
return std::equal(n.m_number, n.m_number+number_size, m_number);
|
||||
return std::equal(n.m_number, n.m_number + number_size, m_number);
|
||||
}
|
||||
bool operator!=(sha1_hash const& n) const
|
||||
{
|
||||
return !std::equal(n.m_number, n.m_number+number_size, m_number);
|
||||
return !std::equal(n.m_number, n.m_number + number_size, m_number);
|
||||
}
|
||||
bool operator<(sha1_hash const& n) const
|
||||
{
|
||||
|
@ -155,7 +148,10 @@ namespace libtorrent
|
|||
return false;
|
||||
}
|
||||
|
||||
int count_leading_zeroes() const;
|
||||
int count_leading_zeroes() const
|
||||
{
|
||||
return aux::clz({m_number, number_size});
|
||||
}
|
||||
|
||||
// returns a bit-wise negated copy of the sha1-hash
|
||||
sha1_hash operator~() const
|
||||
|
@ -281,4 +277,3 @@ namespace std {
|
|||
}
|
||||
|
||||
#endif // TORRENT_SHA1_HASH_HPP_INCLUDED
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ libtorrent_rasterbar_la_SOURCES = \
|
|||
xml_parse.cpp \
|
||||
version.cpp \
|
||||
file_progress.cpp \
|
||||
ffs.cpp \
|
||||
\
|
||||
$(KADEMLIA_SOURCES)
|
||||
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2014-2016, Arvid Norberg, Alden Torres
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/aux_/ffs.hpp"
|
||||
#include "libtorrent/aux_/byteswap.hpp"
|
||||
|
||||
#include "libtorrent/aux_/disable_warnings_push.hpp"
|
||||
|
||||
#if (defined _MSC_VER && _MSC_VER >= 1600)
|
||||
#include <nmmintrin.h>
|
||||
#endif
|
||||
|
||||
#include "libtorrent/aux_/disable_warnings_pop.hpp"
|
||||
|
||||
namespace libtorrent { namespace aux
|
||||
{
|
||||
int clz_sw(span<std::uint32_t const> buf)
|
||||
{
|
||||
int num = int(buf.size());
|
||||
std::uint32_t const* ptr = buf.data();
|
||||
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
if (ptr[i] == 0) continue;
|
||||
std::uint32_t v = aux::network_to_host(ptr[i]);
|
||||
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
|
||||
static const int MultiplyDeBruijnBitPosition[32] =
|
||||
{
|
||||
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
||||
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
|
||||
};
|
||||
|
||||
v |= v >> 1; // first round down to one less than a power of 2
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
|
||||
return i * 32 + 31 - MultiplyDeBruijnBitPosition[
|
||||
static_cast<std::uint32_t>(v * 0x07C4ACDDU) >> 27];
|
||||
}
|
||||
|
||||
return num * 32;
|
||||
}
|
||||
|
||||
int clz_hw(span<std::uint32_t const> buf)
|
||||
{
|
||||
int num = int(buf.size());
|
||||
std::uint32_t const* ptr = buf.data();
|
||||
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
if (ptr[i] == 0) continue;
|
||||
std::uint32_t v = aux::network_to_host(ptr[i]);
|
||||
|
||||
#if TORRENT_HAS_BUILTIN_CLZ
|
||||
return i * 32 + __builtin_clz(v);
|
||||
#elif defined _MSC_VER
|
||||
DWORD pos;
|
||||
_BitScanReverse(&pos, v);
|
||||
return i * 32 + 31 - pos;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
return num * 32;
|
||||
}
|
||||
|
||||
int clz(span<std::uint32_t const> buf)
|
||||
{
|
||||
#if TORRENT_HAS_BUILTIN_CLZ || defined _MSC_VER
|
||||
return aux::clz_hw(buf);
|
||||
#else
|
||||
return aux::clz_sw(buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
}}
|
|
@ -31,7 +31,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
#include "libtorrent/sha1_hash.hpp"
|
||||
#include "libtorrent/aux_/cpuid.hpp"
|
||||
#include "libtorrent/hex.hpp" // to_hex, from_hex
|
||||
|
||||
#if TORRENT_USE_IOSTREAM
|
||||
|
@ -63,45 +62,6 @@ namespace libtorrent
|
|||
|
||||
#endif // TORRENT_USE_IOSTREAM
|
||||
|
||||
int sha1_hash::count_leading_zeroes() const
|
||||
{
|
||||
int ret = 0;
|
||||
for (int i = 0; i < number_size; ++i)
|
||||
{
|
||||
std::uint32_t v = aux::network_to_host(m_number[i]);
|
||||
if (v == 0)
|
||||
{
|
||||
ret += 32;
|
||||
continue;
|
||||
}
|
||||
|
||||
#if TORRENT_HAS_BUILTIN_CLZ
|
||||
return ret + __builtin_clz(v);
|
||||
#elif TORRENT_HAS_SSE && defined _MSC_VER
|
||||
DWORD pos;
|
||||
_BitScanReverse(&pos, v);
|
||||
return ret + 31 - pos;
|
||||
#else
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious
|
||||
static const int MultiplyDeBruijnBitPosition[32] =
|
||||
{
|
||||
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
||||
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
|
||||
};
|
||||
|
||||
v |= v >> 1; // first round down to one less than a power of 2
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
|
||||
return ret + MultiplyDeBruijnBitPosition[
|
||||
static_cast<std::uint32_t>(v * 0x07C4ACDDU) >> 27];
|
||||
#endif
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
sha1_hash& sha1_hash::operator<<=(int n)
|
||||
{
|
||||
TORRENT_ASSERT(n >= 0);
|
||||
|
@ -130,12 +90,12 @@ namespace libtorrent
|
|||
for (int i = 0; i < number_size - 1; ++i)
|
||||
{
|
||||
m_number[i] <<= n;
|
||||
m_number[i+1] = aux::network_to_host(m_number[i+1]);
|
||||
m_number[i] |= m_number[i+1] >> (32 - n);
|
||||
m_number[i + 1] = aux::network_to_host(m_number[i + 1]);
|
||||
m_number[i] |= m_number[i + 1] >> (32 - n);
|
||||
m_number[i] = aux::host_to_network(m_number[i]);
|
||||
}
|
||||
m_number[number_size-1] <<= n;
|
||||
m_number[number_size-1] = aux::host_to_network(m_number[number_size-1]);
|
||||
m_number[number_size - 1] <<= n;
|
||||
m_number[number_size - 1] = aux::host_to_network(m_number[number_size - 1]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -162,13 +122,13 @@ namespace libtorrent
|
|||
// byte order, so they have to be byteswapped before
|
||||
// applying the shift operations, and then byteswapped
|
||||
// back again.
|
||||
m_number[number_size-1] = aux::network_to_host(m_number[number_size-1]);
|
||||
m_number[number_size - 1] = aux::network_to_host(m_number[number_size - 1]);
|
||||
|
||||
for (int i = number_size - 1; i > 0; --i)
|
||||
{
|
||||
m_number[i] >>= n;
|
||||
m_number[i-1] = aux::network_to_host(m_number[i-1]);
|
||||
m_number[i] |= (m_number[i-1] << (32 - n)) & 0xffffffff;
|
||||
m_number[i - 1] = aux::network_to_host(m_number[i - 1]);
|
||||
m_number[i] |= (m_number[i - 1] << (32 - n)) & 0xffffffff;
|
||||
m_number[i] = aux::host_to_network(m_number[i]);
|
||||
}
|
||||
m_number[0] >>= n;
|
||||
|
@ -178,4 +138,3 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -153,6 +153,7 @@ test-suite libtorrent :
|
|||
[ run test_sha1_hash.cpp ]
|
||||
[ run test_bitfield.cpp ]
|
||||
[ run test_crc32.cpp ]
|
||||
[ run test_ffs.cpp ]
|
||||
[ run test_receive_buffer.cpp ]
|
||||
[ run test_alert_manager.cpp ]
|
||||
[ run test_magnet.cpp ]
|
||||
|
@ -230,6 +231,7 @@ alias arm-tests :
|
|||
test_sha1_hash
|
||||
test_bitfield
|
||||
test_crc32
|
||||
test_ffs
|
||||
;
|
||||
|
||||
explicit arm-tests ;
|
||||
|
|
|
@ -43,7 +43,8 @@ test_programs = \
|
|||
test_enum_net \
|
||||
test_file_progress \
|
||||
test_linked_list \
|
||||
test_direct_dht
|
||||
test_direct_dht \
|
||||
test_ffs
|
||||
|
||||
if ENABLE_TESTS
|
||||
check_PROGRAMS = $(test_programs)
|
||||
|
@ -224,6 +225,7 @@ test_remap_files_SOURCES = test_remap_files.cpp
|
|||
test_file_progress_SOURCES = test_file_progress.cpp
|
||||
test_linked_list_SOURCES = test_linked_list.cpp
|
||||
test_direct_dht_SOURCES = test_direct_dht.cpp
|
||||
test_ffs_SOURCES = test_ffs.cpp
|
||||
|
||||
LDADD = libtest.la $(top_builddir)/src/libtorrent-rasterbar.la
|
||||
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2015, Arvid Norberg, Alden Torres
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include "test.hpp"
|
||||
#include "libtorrent/span.hpp"
|
||||
#include "libtorrent/hex.hpp" // from_hex
|
||||
#include "libtorrent/aux_/ffs.hpp"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
static void to_binary(char const* s, std::uint32_t* buf)
|
||||
{
|
||||
aux::from_hex({s, 40}, reinterpret_cast<char*>(&buf[0]));
|
||||
}
|
||||
|
||||
TORRENT_TEST(clz)
|
||||
{
|
||||
std::vector<std::pair<char const*, int>> const tests = {
|
||||
{ "ffffffffffffffffffffffffffffffffffffffff", 0 },
|
||||
{ "0000000000000000000000000000000000000000", 160 },
|
||||
{ "fff0000000000000000000000000000000000000", 0 },
|
||||
{ "7ff0000000000000000000000000000000000000", 1 },
|
||||
{ "3ff0000000000000000000000000000000000000", 2 },
|
||||
{ "1ff0000000000000000000000000000000000000", 3 },
|
||||
{ "0ff0000000000000000000000000000000000000", 4 },
|
||||
{ "07f0000000000000000000000000000000000000", 5 },
|
||||
{ "03f0000000000000000000000000000000000000", 6 },
|
||||
{ "01f0000000000000000000000000000000000000", 7 },
|
||||
{ "00f0000000000000000000000000000000000000", 8 },
|
||||
{ "0070000000000000000000000000000000000000", 9 },
|
||||
{ "0030000000000000000000000000000000000000", 10 },
|
||||
{ "0010000000000000000000000000000000000000", 11 },
|
||||
{ "0000000ffff00000000000000000000000000000", 28 },
|
||||
{ "00000007fff00000000000000000000000000000", 29 },
|
||||
{ "00000003fff00000000000000000000000000000", 30 },
|
||||
{ "00000001fff00000000000000000000000000000", 31 },
|
||||
{ "00000000fff00000000000000000000000000000", 32 },
|
||||
{ "000000007ff00000000000000000000000000000", 33 },
|
||||
{ "000000003ff00000000000000000000000000000", 34 },
|
||||
{ "000000001ff00000000000000000000000000000", 35 },
|
||||
};
|
||||
|
||||
for (auto const& t : tests)
|
||||
{
|
||||
std::fprintf(stderr, "%s\n", t.first);
|
||||
std::uint32_t buf[5];
|
||||
to_binary(t.first, buf);
|
||||
TEST_EQUAL(aux::clz_sw({buf, 5}), t.second);
|
||||
TEST_EQUAL(aux::clz_hw({buf, 5}), t.second);
|
||||
TEST_EQUAL(aux::clz({buf, 5}), t.second);
|
||||
}
|
||||
}
|
|
@ -143,8 +143,4 @@ TORRENT_TEST(count_leading_zeroes)
|
|||
std::fprintf(stderr, "%s\n", t.first);
|
||||
TEST_EQUAL(to_hash(t.first).count_leading_zeroes(), t.second);
|
||||
}
|
||||
|
||||
#if TORRENT_HAS_ARM && !TORRENT_HAS_BUILTIN_CLZ
|
||||
#error "expected built-in clz for arm architecture"
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue