transition to use boost.random instead of rand() and custom pseudo random generator
This commit is contained in:
parent
fcf2f6234b
commit
524384045c
8
Jamfile
8
Jamfile
|
@ -179,11 +179,13 @@ rule linking ( properties * )
|
|||
result += <define>BOOST_ALL_DYN_LINK ;
|
||||
result += <library>/boost/system//boost_system/<link>static/<define>BOOST_ALL_DYN_LINK ;
|
||||
result += <library>/boost/chrono//boost_chrono/<link>static/<define>BOOST_ALL_DYN_LINK ;
|
||||
result += <library>/boost/random//boost_random/<link>static/<define>BOOST_ALL_DYN_LINK ;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += <library>/boost/system//boost_system/<link>static ;
|
||||
result += <library>/boost/chrono//boost_chrono/<link>static ;
|
||||
result += <library>/boost/chrono//boost_random/<link>static ;
|
||||
}
|
||||
|
||||
if <toolset>gcc in $(properties) && <link>shared in $(properties)
|
||||
|
@ -196,6 +198,7 @@ rule linking ( properties * )
|
|||
{
|
||||
result += <library>/boost/system//boost_system/<link>shared ;
|
||||
result += <library>/boost/chrono//boost_chrono/<link>shared ;
|
||||
result += <library>/boost/chrono//boost_random/<link>shared ;
|
||||
}
|
||||
result += <include>$(BOOST_ROOT)
|
||||
<define>BOOST_ALL_NO_LIB
|
||||
|
@ -207,6 +210,7 @@ rule linking ( properties * )
|
|||
{
|
||||
result += <library>boost_system ;
|
||||
result += <library>boost_chrono ;
|
||||
result += <library>boost_random ;
|
||||
|
||||
# on mac the boost headers are installed in
|
||||
# a directory that isn't automatically accessable
|
||||
|
@ -487,6 +491,10 @@ lib boost_chrono : : <target-os>darwin <name>boost_chrono-mt $(boost-library-sea
|
|||
lib boost_chrono : : <target-os>solaris <name>boost_chrono $(boost-library-search-path) ;
|
||||
lib boost_chrono : : <name>boost_chrono ;
|
||||
|
||||
lib boost_random : : <target-os>darwin <name>boost_random-mt $(boost-library-search-path) ;
|
||||
lib boost_random : : <target-os>solaris <name>boost_random $(boost-library-search-path) ;
|
||||
lib boost_random : : <name>boost_random ;
|
||||
|
||||
# openssl on linux/bsd/macos etc.
|
||||
lib gcrypt : : <name>gcrypt <link>shared <search>/opt/local/lib ;
|
||||
lib z : : <link>shared <name>z <search>/usr/lib ;
|
||||
|
|
|
@ -18,6 +18,6 @@ rm -f bindings/python/Makefile bindings/python/Makefile.in
|
|||
chmod a-x docs/*.rst docs/*.htm* src/*.cpp include/libtorrent/*.hpp
|
||||
|
||||
./autotool.sh
|
||||
./configure --enable-python-binding --enable-examples=yes --enable-encryption --enable-tests=yes --with-boost-system=mt --with-boost-python=mt --enable-tests
|
||||
./configure --enable-python-binding --enable-examples=yes --enable-encryption --enable-tests=yes --with-boost-system=mt --with-boost-chrono=mt --with-boost-random=mt --with-boost-python=mt --enable-tests
|
||||
make V=1 -j8 check distcheck
|
||||
|
||||
|
|
12
configure.ac
12
configure.ac
|
@ -119,12 +119,20 @@ AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
|
|||
AS_ECHO
|
||||
AS_ECHO "Checking for boost libraries:"
|
||||
|
||||
AX_BOOST_BASE([1.36])
|
||||
AX_BOOST_BASE([1.47])
|
||||
|
||||
AX_BOOST_SYSTEM()
|
||||
AS_IF([test -z "$BOOST_SYSTEM_LIB"],
|
||||
[AC_MSG_ERROR(Boost.System library not found. Try using --with-boost-system=lib)])
|
||||
|
||||
AX_BOOST_CHRONO()
|
||||
AS_IF([test -z "$BOOST_CHRONO_LIB"],
|
||||
[AC_MSG_ERROR(Boost.Chrono library not found. Try using --with-boost-chrono=lib)])
|
||||
|
||||
AX_BOOST_RANDOM()
|
||||
AS_IF([test -z "$BOOST_RANDOM_LIB"],
|
||||
[AC_MSG_ERROR(Boost.Random library not found. Try using --with-boost-random=lib)])
|
||||
|
||||
CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
|
||||
LDFLAGS="$BOOST_LDFLAGS $LDFLAGS"
|
||||
|
||||
|
@ -747,6 +755,8 @@ Boost libraries:
|
|||
CPPFlags: ${BOOST_CPPFLAGS}
|
||||
LDFlags: ${BOOST_LDFLAGS}
|
||||
boost.system: ${BOOST_SYSTEM_LIB}
|
||||
boost.chrono: ${BOOST_CHRONO_LIB}
|
||||
boost.random: ${BOOST_RANDOM_LIB}
|
||||
END
|
||||
|
||||
AS_IF([test "x$ARG_ENABLE_PYTHON_BINDING" = "xyes"], [
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
example_programs = \
|
||||
client_test \
|
||||
stats_counters \
|
||||
dump_torrent \
|
||||
make_torrent \
|
||||
simple_client \
|
||||
|
|
|
@ -102,7 +102,6 @@ nobase_include_HEADERS = \
|
|||
platform_util.hpp \
|
||||
policy.hpp \
|
||||
proxy_base.hpp \
|
||||
ptime.hpp \
|
||||
puff.hpp \
|
||||
random.hpp \
|
||||
resolver.hpp \
|
||||
|
|
|
@ -35,6 +35,5 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent
|
||||
{
|
||||
void random_seed(boost::uint32_t v);
|
||||
boost::uint32_t TORRENT_EXTRA_EXPORT random();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_boost_chrono.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_BOOST_CHRONO
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Test for System library from the Boost C++ libraries. The macro requires
|
||||
# a preceding call to AX_BOOST_BASE. Further documentation is available at
|
||||
# <http://randspringer.de/boost/index.html>.
|
||||
#
|
||||
# This macro calls:
|
||||
#
|
||||
# AC_SUBST(BOOST_CHRONO_LIB)
|
||||
#
|
||||
# And sets:
|
||||
#
|
||||
# HAVE_BOOST_CHRONO
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2012 Xiyue Deng <manphiz@gmail.com>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 1
|
||||
|
||||
AC_DEFUN([AX_BOOST_CHRONO],
|
||||
[
|
||||
AC_ARG_WITH([boost-chrono],
|
||||
AS_HELP_STRING([--with-boost-chrono@<:@=special-lib@:>@],
|
||||
[use the Chrono library from boost - it is possible to specify a certain library for the linker
|
||||
e.g. --with-boost-chrono=boost_chrono-gcc-mt ]),
|
||||
[
|
||||
if test "$withval" = "no"; then
|
||||
want_boost="no"
|
||||
elif test "$withval" = "yes"; then
|
||||
want_boost="yes"
|
||||
ax_boost_user_chrono_lib=""
|
||||
else
|
||||
want_boost="yes"
|
||||
ax_boost_user_chrono_lib="$withval"
|
||||
fi
|
||||
],
|
||||
[want_boost="yes"]
|
||||
)
|
||||
|
||||
if test "x$want_boost" = "xyes"; then
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_CANONICAL_BUILD])
|
||||
CPPFLAGS_SAVED="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
export CPPFLAGS
|
||||
|
||||
LDFLAGS_SAVED="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
|
||||
export LDFLAGS
|
||||
|
||||
AC_CACHE_CHECK(whether the Boost::Chrono library is available,
|
||||
ax_cv_boost_chrono,
|
||||
[AC_LANG_PUSH([C++])
|
||||
CXXFLAGS_SAVE=$CXXFLAGS
|
||||
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <boost/chrono.hpp>]],
|
||||
[[boost::chrono::system_clock::time_point time;]])],
|
||||
ax_cv_boost_chrono=yes, ax_cv_boost_chrono=no)
|
||||
CXXFLAGS=$CXXFLAGS_SAVE
|
||||
AC_LANG_POP([C++])
|
||||
])
|
||||
if test "x$ax_cv_boost_chrono" = "xyes"; then
|
||||
AC_SUBST(BOOST_CPPFLAGS)
|
||||
|
||||
AC_DEFINE(HAVE_BOOST_CHRONO,,[define if the Boost::Chrono library is available])
|
||||
BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'`
|
||||
|
||||
LDFLAGS_SAVE=$LDFLAGS
|
||||
if test "x$ax_boost_user_chrono_lib" = "x"; then
|
||||
for libextension in `ls $BOOSTLIBDIR/libboost_chrono*.so* $BOOSTLIBDIR/libboost_chrono*.dylib* $BOOSTLIBDIR/libboost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^lib\(boost_chrono.*\)\.so.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.dylib.*$;\1;' -e 's;^lib\(boost_chrono.*\)\.a.*$;\1;'` ; do
|
||||
ax_lib=${libextension}
|
||||
AC_CHECK_LIB($ax_lib, exit,
|
||||
[BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break],
|
||||
[link_chrono="no"])
|
||||
done
|
||||
if test "x$link_chrono" != "xyes"; then
|
||||
for libextension in `ls $BOOSTLIBDIR/boost_chrono*.dll* $BOOSTLIBDIR/boost_chrono*.a* 2>/dev/null | sed 's,.*/,,' | sed -e 's;^\(boost_chrono.*\)\.dll.*$;\1;' -e 's;^\(boost_chrono.*\)\.a.*$;\1;'` ; do
|
||||
ax_lib=${libextension}
|
||||
AC_CHECK_LIB($ax_lib, exit,
|
||||
[BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break],
|
||||
[link_chrono="no"])
|
||||
done
|
||||
fi
|
||||
|
||||
else
|
||||
for ax_lib in $ax_boost_user_chrono_lib boost_chrono-$ax_boost_user_chrono_lib; do
|
||||
AC_CHECK_LIB($ax_lib, exit,
|
||||
[BOOST_CHRONO_LIB="-l$ax_lib"; AC_SUBST(BOOST_CHRONO_LIB) link_chrono="yes"; break],
|
||||
[link_chrono="no"])
|
||||
done
|
||||
|
||||
fi
|
||||
if test "x$ax_lib" = "x"; then
|
||||
AC_MSG_ERROR(Could not find a version of the library!)
|
||||
fi
|
||||
if test "x$link_chrono" = "xno"; then
|
||||
AC_MSG_ERROR(Could not link against $ax_lib !)
|
||||
fi
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS_SAVED"
|
||||
LDFLAGS="$LDFLAGS_SAVED"
|
||||
fi
|
||||
])
|
||||
|
|
@ -44,6 +44,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/alert_dispatcher.hpp"
|
||||
#include "libtorrent/performance_counters.hpp"
|
||||
|
||||
#ifdef TORRENT_DEBUG
|
||||
#include "libtorrent/random.hpp"
|
||||
#endif
|
||||
|
||||
#if TORRENT_USE_PURGABLE_CONTROL
|
||||
#include <mach/mach.h>
|
||||
// see comments at:
|
||||
|
@ -1201,7 +1205,7 @@ void block_cache::insert_blocks(cached_piece_entry* pe, int block, file::iovec_t
|
|||
VM_PURGABLE_SET_STATE,
|
||||
&state);
|
||||
#ifdef TORRENT_DEBUG
|
||||
// if ((rand() % 200) == 0) ret = 1;
|
||||
// if ((random() % 200) == 0) ret = 1;
|
||||
#endif
|
||||
if (ret != KERN_SUCCESS || (state & VM_PURGABLE_EMPTY))
|
||||
{
|
||||
|
@ -1250,7 +1254,7 @@ bool block_cache::inc_block_refcount(cached_piece_entry* pe, int block, int reas
|
|||
VM_PURGABLE_SET_STATE,
|
||||
&state);
|
||||
#ifdef TORRENT_DEBUG
|
||||
// if ((rand() % 200) == 0) ret = 1;
|
||||
// if ((random() % 200) == 0) ret = 1;
|
||||
#endif
|
||||
if (ret != KERN_SUCCESS || (state & VM_PURGABLE_EMPTY))
|
||||
{
|
||||
|
@ -1312,7 +1316,7 @@ void block_cache::dec_block_refcount(cached_piece_entry* pe, int block, int reas
|
|||
VM_PURGABLE_SET_STATE,
|
||||
&state);
|
||||
#ifdef TORRENT_DEBUG
|
||||
// if ((rand() % 200) == 0) ret = 1;
|
||||
// if ((random() % 200) == 0) ret = 1;
|
||||
#endif
|
||||
if (ret != KERN_SUCCESS || (state & VM_PURGABLE_EMPTY))
|
||||
{
|
||||
|
|
|
@ -112,7 +112,7 @@ node_impl::node_impl(alert_dispatcher* alert_disp
|
|||
, m_counters(cnt)
|
||||
{
|
||||
m_secret[0] = random();
|
||||
m_secret[1] = std::rand();
|
||||
m_secret[1] = random();
|
||||
}
|
||||
|
||||
bool node_impl::verify_token(std::string const& token, char const* info_hash
|
||||
|
|
|
@ -33,40 +33,21 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/random.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include <boost/random/random_device.hpp>
|
||||
#include <boost/random/mersenne_twister.hpp>
|
||||
#include <boost/random/uniform_int_distribution.hpp>
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
boost::uint32_t x = 123456789;
|
||||
#ifdef TORRENT_USE_ASSERTS
|
||||
bool seeded = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void random_seed(boost::uint32_t v)
|
||||
{
|
||||
x = v;
|
||||
#ifdef TORRENT_USE_ASSERTS
|
||||
seeded = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// this is an xorshift random number generator
|
||||
// see: http://en.wikipedia.org/wiki/Xorshift
|
||||
boost::uint32_t random()
|
||||
{
|
||||
TORRENT_ASSERT(seeded);
|
||||
using boost::random::random_device;
|
||||
using boost::random::mt19937;
|
||||
using boost::random::uniform_int_distribution;
|
||||
|
||||
static boost::uint32_t y = 362436069;
|
||||
static boost::uint32_t z = 521288629;
|
||||
static boost::uint32_t w = 88675123;
|
||||
boost::uint32_t t;
|
||||
|
||||
t = x ^ (x << 11);
|
||||
x = y; y = z; z = w;
|
||||
return w = w ^ (w >> 19) ^ (t ^ (t >> 8));
|
||||
static random_device dev;
|
||||
static mt19937 random_engine(dev());
|
||||
return uniform_int_distribution<boost::uint32_t>(0, UINT_MAX)(random_engine);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -313,14 +313,6 @@ namespace aux {
|
|||
}
|
||||
#endif // TORRENT_STATS
|
||||
|
||||
struct seed_random_generator
|
||||
{
|
||||
seed_random_generator()
|
||||
{
|
||||
random_seed((unsigned int)((time_now().time_since_epoch().count()) & 0xffffffff));
|
||||
}
|
||||
};
|
||||
|
||||
void session_impl::init_peer_class_filter(bool unlimited_local)
|
||||
{
|
||||
// set the default peer_class_filter to use the local peer class
|
||||
|
@ -543,8 +535,6 @@ namespace aux {
|
|||
TORRENT_ASSERT_VAL(!ec, ec);
|
||||
|
||||
// ---- generate a peer id ----
|
||||
static seed_random_generator seeder;
|
||||
|
||||
std::string print = cl_fprint.to_string();
|
||||
TORRENT_ASSERT_VAL(print.length() <= 20, print.length());
|
||||
|
||||
|
@ -1852,8 +1842,8 @@ namespace aux {
|
|||
{
|
||||
#ifdef TORRENT_DEBUG
|
||||
// make it obvious that the return value is undefined
|
||||
ret.upload_limit = rand();
|
||||
ret.download_limit = rand();
|
||||
ret.upload_limit = random();
|
||||
ret.download_limit = random();
|
||||
ret.label.resize(20);
|
||||
url_random(&ret.label[0], &ret.label[0] + 20);
|
||||
ret.ignore_unchoke_slots = false;
|
||||
|
|
|
@ -1623,7 +1623,7 @@ namespace libtorrent
|
|||
SSL_CTX_set_cert_store(ssl_ctx, cert_store);
|
||||
#if 0
|
||||
char filename[100];
|
||||
snprintf(filename, sizeof(filename), "/tmp/%d.pem", rand());
|
||||
snprintf(filename, sizeof(filename), "/tmp/%u.pem", random());
|
||||
FILE* f = fopen(filename, "w+");
|
||||
fwrite(cert.c_str(), cert.size(), 1, f);
|
||||
fclose(f);
|
||||
|
|
|
@ -1899,7 +1899,7 @@ bool utp_socket_impl::send_pkt(int flags)
|
|||
error_code ec;
|
||||
#ifdef TORRENT_DEBUG
|
||||
// simulate 1% packet loss
|
||||
// if ((rand() % 100) > 0)
|
||||
// if ((random() % 100) > 0)
|
||||
#endif
|
||||
m_sm->send_packet(udp::endpoint(m_remote_address, m_port)
|
||||
, (char const*)h, p->size, ec
|
||||
|
|
|
@ -90,6 +90,7 @@ feature.compose <launcher>valgrind : <testing.launcher>"valgrind --tool=memcheck
|
|||
|
||||
test-suite libtorrent :
|
||||
[ run test_socket_io.cpp ]
|
||||
[ run test_random.cpp ]
|
||||
[ run test_utf8.cpp ]
|
||||
[ run test_gzip.cpp ]
|
||||
[ run test_bitfield.cpp ]
|
||||
|
|
|
@ -434,8 +434,6 @@ bool get_item_cb(dht::item& i)
|
|||
// TODO: 3 test obfuscated_get_peers
|
||||
int test_main()
|
||||
{
|
||||
random_seed(time_now_hires().time_since_epoch().count());
|
||||
|
||||
dht_settings sett;
|
||||
sett.max_torrents = 4;
|
||||
sett.max_dht_items = 4;
|
||||
|
|
|
@ -182,8 +182,6 @@ int test_main()
|
|||
const int repcount = 128;
|
||||
#endif
|
||||
|
||||
random_seed(time_now_hires().time_since_epoch().count());
|
||||
|
||||
for (int rep = 0; rep < repcount; ++rep)
|
||||
{
|
||||
dh_key_exchange DH1, DH2;
|
||||
|
|
|
@ -271,8 +271,6 @@ int test_pick(boost::shared_ptr<piece_picker> const& p, int options = piece_pick
|
|||
|
||||
int test_main()
|
||||
{
|
||||
random_seed(time_now_hires().time_since_epoch().count());
|
||||
|
||||
tcp::endpoint endp;
|
||||
piece_picker::downloading_piece st;
|
||||
#if TORRENT_USE_ASSERTS
|
||||
|
|
|
@ -133,8 +133,6 @@ private:
|
|||
|
||||
int test_main()
|
||||
{
|
||||
random_seed(time_now_hires().time_since_epoch().count());
|
||||
|
||||
torrent_peer_allocator allocator;
|
||||
external_ip ext_ip;
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2014, Arvid Norberg
|
||||
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 "setup_transfer.hpp"
|
||||
#include "random.hpp"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
int test_main()
|
||||
{
|
||||
|
||||
const int repetitions = 200000;
|
||||
|
||||
for (int byte = 0; byte < 4; ++byte)
|
||||
{
|
||||
int buckets[256];
|
||||
memset(buckets, 0, sizeof(buckets));
|
||||
|
||||
for (int i = 0; i < repetitions; ++i)
|
||||
{
|
||||
boost::uint32_t val = libtorrent::random();
|
||||
val >>= byte * 8;
|
||||
++buckets[val & 0xff];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
const int expected = repetitions / 256;
|
||||
// expect each bucket to be within 15% of the expected value
|
||||
fprintf(stderr, "%d: %f\n", i, float(buckets[i] - expected) * 100.f / expected);
|
||||
TEST_CHECK(abs(buckets[i] - expected) < expected / 6);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue