From de7417f0dee3cea7d5b6084d93108caf1a40e19a Mon Sep 17 00:00:00 2001 From: neverchanje Date: Sat, 15 Sep 2018 20:35:16 +0800 Subject: [PATCH 01/11] util: make rand a standalone util decoupled from rdsn runtime --- include/dsn/c/api_layer1.h | 11 ------- include/dsn/tool-api/env_provider.h | 5 --- include/dsn/utility/rand.h | 31 +++++++++++++++++++ src/core/core/env_provider.cpp | 22 ------------- src/core/core/fail_point.cpp | 3 +- src/core/core/partition_resolver_simple.cpp | 2 +- src/core/core/rand.cc | 23 ++++++++++++++ src/core/core/rpc_engine.cpp | 2 +- src/core/core/service_api_c.cpp | 16 ---------- src/core/core/task.cpp | 2 +- src/core/tests/env.cpp | 5 +-- src/core/tests/service_api_c.cpp | 3 +- src/core/tests/utils.cpp | 3 +- src/core/tools/common/asio_net_provider.cpp | 2 +- src/core/tools/common/fault_injector.cpp | 31 ++++++++++--------- src/core/tools/common/network.sim.cpp | 2 +- src/core/tools/simulator/env.sim.cpp | 9 ++++-- src/core/tools/simulator/scheduler.cpp | 4 +-- src/core/tools/simulator/task_engine.sim.cpp | 7 +++-- .../failure_detector_multimaster.cpp | 2 +- src/dist/replication/lib/replica.cpp | 2 +- src/dist/replication/lib/replica_stub.cpp | 6 ++-- .../replication/test/meta_test/misc/misc.cpp | 4 +-- src/tests/dsn/fds_service_test.cpp | 8 ++--- 24 files changed, 107 insertions(+), 98 deletions(-) create mode 100644 include/dsn/utility/rand.h create mode 100644 src/core/core/rand.cc diff --git a/include/dsn/c/api_layer1.h b/include/dsn/c/api_layer1.h index e41779adf1..3a102d1975 100644 --- a/include/dsn/c/api_layer1.h +++ b/include/dsn/c/api_layer1.h @@ -345,20 +345,9 @@ replace the underneath implementation of these primitives. extern DSN_API uint64_t dsn_runtime_init_time_ms(); extern DSN_API uint64_t dsn_now_ns(); -/*! return [min, max] */ -extern DSN_API uint64_t dsn_random64(uint64_t min, uint64_t max); - __inline uint64_t dsn_now_us() { return dsn_now_ns() / 1000; } __inline uint64_t dsn_now_ms() { return dsn_now_ns() / 1000000; } -/*! return [min, max] */ -__inline uint32_t dsn_random32(uint32_t min, uint32_t max) -{ - return (uint32_t)(dsn_random64(min, max)); -} - -__inline double dsn_probability() { return (double)(dsn_random64(0, 1000000000)) / 1000000000.0; } - /*@}*/ /*! diff --git a/include/dsn/tool-api/env_provider.h b/include/dsn/tool-api/env_provider.h index dc7bb75152..a08d0962da 100644 --- a/include/dsn/tool-api/env_provider.h +++ b/include/dsn/tool-api/env_provider.h @@ -59,11 +59,6 @@ class env_provider env_provider(env_provider *inner_provider); DSN_API virtual uint64_t now_ns() const; - - DSN_API virtual uint64_t random64(uint64_t min, uint64_t max); - -protected: - DSN_API static void set_thread_local_random_seed(int s); }; /*@}*/ } // end namespace diff --git a/include/dsn/utility/rand.h b/include/dsn/utility/rand.h new file mode 100644 index 0000000000..fc594fe535 --- /dev/null +++ b/include/dsn/utility/rand.h @@ -0,0 +1,31 @@ +// Copyright (c) 2017, Xiaomi, Inc. All rights reserved. +// This source code is licensed under the Apache License Version 2.0, which +// can be found in the LICENSE file in the root directory of this source tree. + +#pragma once + +#include +#include + +namespace dsn { +namespace rand { + +// uint64n returns, as an uint64_t, a non-negative pseudo-random number in [min, max). +extern uint64_t uint64in(uint64_t min, uint64_t max); + +// uint64n returns, as an uint64_t, a non-negative pseudo-random number in [0, n). +inline uint64_t uint64n(uint64_t n) { return uint64in(0, n - 1); } + +// uint32n returns, as an uint32_t, a non-negative pseudo-random number in [0, n). +inline uint32_t uint32n(uint32_t n) { return static_cast(uint64n(n)); } + +// uint32n returns, as an uint32_t, a non-negative pseudo-random number in [min, max). +inline uint32_t uint32in(uint32_t min, uint32_t max) { return uint32n(max - min) + min; } + +// float64 returns, as a double, a pseudo-random number in [0.0,1.0). +inline double float64n() { return uint64n(1000000000) / 1000000000.0; } + +extern void set_seed_thread_local_rng(uint64_t seed); + +} // namespace rand +} // namespace dsn diff --git a/src/core/core/env_provider.cpp b/src/core/core/env_provider.cpp index 8515246964..3ed2e6923b 100644 --- a/src/core/core/env_provider.cpp +++ b/src/core/core/env_provider.cpp @@ -48,26 +48,4 @@ env_provider::env_provider(env_provider *inner_provider) {} uint64_t env_provider::now_ns() const { return utils::get_current_physical_time_ns(); } -void env_provider::set_thread_local_random_seed(int s) -{ - if (env_provider__tls_magic != 0xdeadbeef) { - env_provider__rng = - new std::remove_pointer::type(std::random_device{}()); - env_provider__tls_magic = 0xdeadbeef; - } - - env_provider__rng->seed(s); -} - -uint64_t env_provider::random64(uint64_t min, uint64_t max) -{ - dassert(min <= max, "invalid random range"); - if (env_provider__tls_magic != 0xdeadbeef) { - env_provider__rng = - new std::remove_pointer::type(std::random_device{}()); - env_provider__tls_magic = 0xdeadbeef; - } - return std::uniform_int_distribution{min, max}(*env_provider__rng); -} - } // end namespace diff --git a/src/core/core/fail_point.cpp b/src/core/core/fail_point.cpp index d8ad91a482..fb30463a44 100644 --- a/src/core/core/fail_point.cpp +++ b/src/core/core/fail_point.cpp @@ -19,6 +19,7 @@ #include #include +#include namespace dsn { namespace fail { @@ -97,7 +98,7 @@ bool fail_point::parse_from_string(string_view action) const std::string *fail_point::eval() { - uint32_t r = dsn_random32(0, 100); + uint32_t r = rand::uint32in(0, 100); if (r > _freq) { return nullptr; } diff --git a/src/core/core/partition_resolver_simple.cpp b/src/core/core/partition_resolver_simple.cpp index fb4a253804..03048a7468 100644 --- a/src/core/core/partition_resolver_simple.cpp +++ b/src/core/core/partition_resolver_simple.cpp @@ -419,7 +419,7 @@ rpc_address partition_resolver_simple::get_address(const partition_configuration if (config.last_drops.size() == 0) { return rpc_address(); } else { - return config.last_drops[dsn_random32(0, config.last_drops.size() - 1)]; + return config.last_drops[rand::uint32in(0, config.last_drops.size() - 1)]; } } diff --git a/src/core/core/rand.cc b/src/core/core/rand.cc new file mode 100644 index 0000000000..c4a9908c2f --- /dev/null +++ b/src/core/core/rand.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2017, Xiaomi, Inc. All rights reserved. +// This source code is licensed under the Apache License Version 2.0, which +// can be found in the LICENSE file in the root directory of this source tree. + +#pragma once + +#include +#include + +namespace dsn { +namespace rand { + +thread_local std::ranlux48_base g_thread_local_rng; + +/*extern*/ uint64_t uint64in(uint64_t min, uint64_t max) +{ + return std::uniform_int_distribution(min, max)(g_thread_local_rng); +} + +/*extern*/ void set_seed_thread_local_rng(uint64_t seed) { g_thread_local_rng.seed(seed); } + +} // namespace rand +} // namespace dsn diff --git a/src/core/core/rpc_engine.cpp b/src/core/core/rpc_engine.cpp index bca599c32f..b8f3bd38b6 100644 --- a/src/core/core/rpc_engine.cpp +++ b/src/core/core/rpc_engine.cpp @@ -634,7 +634,7 @@ void rpc_engine::call(message_ex *request, const rpc_response_task_ptr &call) { auto &hdr = *request->header; hdr.from_address = primary_address(); - hdr.trace_id = dsn_random64(std::numeric_limits::min(), + hdr.trace_id = rand::uint64in(std::numeric_limits::min(), std::numeric_limits::max()); call_address(request->server_address, request, call); diff --git a/src/core/core/service_api_c.cpp b/src/core/core/service_api_c.cpp index 47cfae8af0..3426ae9f98 100644 --- a/src/core/core/service_api_c.cpp +++ b/src/core/core/service_api_c.cpp @@ -370,22 +370,6 @@ DSN_API void dsn_file_write_vector(dsn_handle_t file, ::dsn::task::get_current_disk()->write(cb); } -//------------------------------------------------------------------------------ -// -// env -// -//------------------------------------------------------------------------------ -DSN_API uint64_t dsn_now_ns() -{ - // return ::dsn::task::get_current_env()->now_ns(); - return ::dsn::service_engine::instance().env()->now_ns(); -} - -DSN_API uint64_t dsn_random64(uint64_t min, uint64_t max) // [min, max] -{ - return ::dsn::service_engine::instance().env()->random64(min, max); -} - static uint64_t s_runtime_init_time_ms; DSN_API uint64_t dsn_runtime_init_time_ms() { return s_runtime_init_time_ms; } diff --git a/src/core/core/task.cpp b/src/core/core/task.cpp index e5b357419f..8e6709e60c 100644 --- a/src/core/core/task.cpp +++ b/src/core/core/task.cpp @@ -431,7 +431,7 @@ void timer_task::enqueue() { // enable timer randomization to avoid lots of timers execution simultaneously if (delay_milliseconds() == 0 && spec().randomize_timer_delay_if_zero) { - set_delay(dsn_random32(0, _interval_milliseconds)); + set_delay(rand::uint32in(0, _interval_milliseconds)); } return task::enqueue(); diff --git a/src/core/tests/env.cpp b/src/core/tests/env.cpp index 2fa01f1a84..f0d6271bf3 100644 --- a/src/core/tests/env.cpp +++ b/src/core/tests/env.cpp @@ -35,6 +35,7 @@ #include #include +#include #include "../tools/simulator/env.sim.h" using namespace ::dsn; @@ -44,10 +45,10 @@ TEST(core, env) uint64_t xs[] = {0, std::numeric_limits::max() - 1, 0xdeadbeef}; for (auto &x : xs) { - auto r = dsn_random64(x, x); + auto r = rand::uint64in(x, x); EXPECT_EQ(r, x); - r = dsn_random64(x, x + 1); + r = rand::uint64in(x, x + 1); EXPECT_TRUE(r == x || r == (x + 1)); } } diff --git a/src/core/tests/service_api_c.cpp b/src/core/tests/service_api_c.cpp index 2ee4511e73..743b28868d 100644 --- a/src/core/tests/service_api_c.cpp +++ b/src/core/tests/service_api_c.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include "core/core/service_engine.h" using namespace dsn; @@ -288,7 +289,7 @@ TEST(core, dsn_env) std::this_thread::sleep_for(std::chrono::milliseconds(1)); uint64_t now2 = dsn_now_ns(); ASSERT_LE(now1 + 1000000, now2); - uint64_t r = dsn_random64(100, 200); + uint64_t r = rand::uint64in(100, 200); ASSERT_LE(100, r); ASSERT_GE(200, r); } diff --git a/src/core/tests/utils.cpp b/src/core/tests/utils.cpp index f6424701be..38e56abac0 100644 --- a/src/core/tests/utils.cpp +++ b/src/core/tests/utils.cpp @@ -42,6 +42,7 @@ #include #include #include +#include using namespace ::dsn; using namespace ::dsn::utils; @@ -59,7 +60,7 @@ TEST(core, crc) { char buffer[24]; for (int i = 0; i < sizeof(buffer) / sizeof(char); i++) { - buffer[i] = dsn_random32(0, 200); + buffer[i] = rand::uint32in(0, 200); } auto c1 = dsn::utils::crc32_calc(buffer, 12, 0); diff --git a/src/core/tools/common/asio_net_provider.cpp b/src/core/tools/common/asio_net_provider.cpp index 1236aee5fa..32f86a9866 100644 --- a/src/core/tools/common/asio_net_provider.cpp +++ b/src/core/tools/common/asio_net_provider.cpp @@ -293,7 +293,7 @@ error_code asio_udp_provider::start(rpc_channel channel, int port, bool client_o // refactored _address.assign_ipv4(get_local_ipv4(), std::numeric_limits::max() - - dsn_random64(std::numeric_limits::min(), + rand::uint64in(std::numeric_limits::min(), std::numeric_limits::max()) % 5000); ::boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address_v4::any(), diff --git a/src/core/tools/common/fault_injector.cpp b/src/core/tools/common/fault_injector.cpp index 278c7e10a1..e948554a4a 100644 --- a/src/core/tools/common/fault_injector.cpp +++ b/src/core/tools/common/fault_injector.cpp @@ -35,6 +35,7 @@ #include #include +#include namespace dsn { namespace tools { @@ -140,7 +141,7 @@ static void fault_on_task_begin(task *this_) { fj_opt &opt = s_fj_opts[this_->spec().code]; if (opt.execution_extra_delay_us_max > 0) { - auto d = dsn_random32(0, opt.execution_extra_delay_us_max); + auto d = rand::uint32in(0, opt.execution_extra_delay_us_max); ddebug( "fault inject %s at %s with delay %u us", this_->spec().name.c_str(), __FUNCTION__, d); std::this_thread::sleep_for(std::chrono::microseconds(d)); @@ -162,14 +163,14 @@ static bool fault_on_aio_call(task *caller, aio_task *callee) { switch (callee->aio()->type) { case AIO_Read: - if (dsn_probability() < s_fj_opts[callee->spec().code].disk_read_fail_ratio) { + if (rand::float64n() < s_fj_opts[callee->spec().code].disk_read_fail_ratio) { ddebug("fault inject %s at %s", callee->spec().name.c_str(), __FUNCTION__); callee->set_error_code(ERR_FILE_OPERATION_FAILED); return false; } break; case AIO_Write: - if (dsn_probability() < s_fj_opts[callee->spec().code].disk_write_fail_ratio) { + if (rand::float64n() < s_fj_opts[callee->spec().code].disk_write_fail_ratio) { ddebug("fault inject %s at %s", callee->spec().name.c_str(), __FUNCTION__); callee->set_error_code(ERR_FILE_OPERATION_FAILED); return false; @@ -186,7 +187,7 @@ static void fault_on_aio_enqueue(aio_task *this_) { fj_opt &opt = s_fj_opts[this_->spec().code]; if (this_->delay_milliseconds() == 0 && task_ext_for_fj::get(this_) == 0) { - this_->set_delay(dsn_random32(opt.disk_io_delay_ms_min, opt.disk_io_delay_ms_max)); + this_->set_delay(rand::uint32in(opt.disk_io_delay_ms_min, opt.disk_io_delay_ms_max)); ddebug("fault inject %s at %s with delay %u ms", this_->spec().name.c_str(), __FUNCTION__, @@ -209,13 +210,13 @@ static void replace_value(std::vector &buffer_list, unsigned int offset) static void corrupt_data(message_ex *request, const std::string &corrupt_type) { if (corrupt_type == "header") - replace_value(request->buffers, dsn_random32(0, sizeof(message_header) - 1)); + replace_value(request->buffers, rand::uint32in(0, sizeof(message_header) - 1)); else if (corrupt_type == "body") replace_value(request->buffers, - dsn_random32(0, request->body_size() - 1) + sizeof(message_header)); + rand::uint32in(0, request->body_size() - 1) + sizeof(message_header)); else if (corrupt_type == "random") replace_value(request->buffers, - dsn_random32(0, request->body_size() + sizeof(message_header) - 1)); + rand::uint32in(0, request->body_size() + sizeof(message_header) - 1)); else { derror("try to inject an unknown data corrupt type: %s", corrupt_type.c_str()); } @@ -225,7 +226,7 @@ static void corrupt_data(message_ex *request, const std::string &corrupt_type) static bool fault_on_rpc_call(task *caller, message_ex *req, rpc_response_task *callee) { fj_opt &opt = s_fj_opts[req->local_rpc_code]; - if (dsn_probability() < opt.rpc_request_drop_ratio) { + if (rand::float64n() < opt.rpc_request_drop_ratio) { ddebug("fault inject %s at %s: %s => %s", req->header->rpc_name, __FUNCTION__, @@ -233,7 +234,7 @@ static bool fault_on_rpc_call(task *caller, message_ex *req, rpc_response_task * req->to_address.to_string()); return false; } else { - if (dsn_probability() < opt.rpc_request_data_corrupted_ratio) { + if (rand::float64n() < opt.rpc_request_data_corrupted_ratio) { ddebug("corrupt the rpc call message from: %s, type: %s", req->header->from_address.to_string(), opt.rpc_message_data_corrupted_type.c_str()); @@ -247,9 +248,9 @@ static void fault_on_rpc_request_enqueue(rpc_request_task *callee) { fj_opt &opt = s_fj_opts[callee->spec().code]; if (callee->delay_milliseconds() == 0 && task_ext_for_fj::get(callee) == 0) { - if (dsn_probability() < opt.rpc_request_delay_ratio) { + if (rand::float64n() < opt.rpc_request_delay_ratio) { callee->set_delay( - dsn_random32(opt.rpc_message_delay_ms_min, opt.rpc_message_delay_ms_max)); + rand::uint32in(opt.rpc_message_delay_ms_min, opt.rpc_message_delay_ms_max)); ddebug("fault inject %s at %s with delay %u ms", callee->spec().name.c_str(), __FUNCTION__, @@ -263,7 +264,7 @@ static void fault_on_rpc_request_enqueue(rpc_request_task *callee) static bool fault_on_rpc_reply(task *caller, message_ex *msg) { fj_opt &opt = s_fj_opts[msg->local_rpc_code]; - if (dsn_probability() < opt.rpc_response_drop_ratio) { + if (rand::float64n() < opt.rpc_response_drop_ratio) { ddebug("fault inject %s at %s: %s => %s", msg->header->rpc_name, __FUNCTION__, @@ -271,7 +272,7 @@ static bool fault_on_rpc_reply(task *caller, message_ex *msg) msg->to_address.to_string()); return false; } else { - if (dsn_probability() < opt.rpc_response_data_corrupted_ratio) { + if (rand::float64n() < opt.rpc_response_data_corrupted_ratio) { ddebug("fault injector corrupt the rpc reply message from: %s, type: %s", msg->header->from_address.to_string(), opt.rpc_message_data_corrupted_type.c_str()); @@ -285,9 +286,9 @@ static void fault_on_rpc_response_enqueue(rpc_response_task *resp) { fj_opt &opt = s_fj_opts[resp->spec().code]; if (resp->delay_milliseconds() == 0 && task_ext_for_fj::get(resp) == 0) { - if (dsn_probability() < opt.rpc_response_delay_ratio) { + if (rand::float64n() < opt.rpc_response_delay_ratio) { resp->set_delay( - dsn_random32(opt.rpc_message_delay_ms_min, opt.rpc_message_delay_ms_max)); + rand::uint32in(opt.rpc_message_delay_ms_min, opt.rpc_message_delay_ms_max)); ddebug("fault inject %s at %s with delay %u ms", resp->spec().name.c_str(), __FUNCTION__, diff --git a/src/core/tools/common/network.sim.cpp b/src/core/tools/common/network.sim.cpp index 9b523d09b6..d660f70f33 100644 --- a/src/core/tools/common/network.sim.cpp +++ b/src/core/tools/common/network.sim.cpp @@ -191,7 +191,7 @@ error_code sim_network_provider::start(rpc_channel channel, int port, bool clien uint32_t sim_network_provider::net_delay_milliseconds() const { return static_cast( - dsn_random32(_min_message_delay_microseconds, _max_message_delay_microseconds)) / + rand::uint32in(_min_message_delay_microseconds, _max_message_delay_microseconds)) / 1000; } } diff --git a/src/core/tools/simulator/env.sim.cpp b/src/core/tools/simulator/env.sim.cpp index 82ff88f07d..2dccb48a5c 100644 --- a/src/core/tools/simulator/env.sim.cpp +++ b/src/core/tools/simulator/env.sim.cpp @@ -36,6 +36,8 @@ #include "env.sim.h" #include "scheduler.h" +#include + namespace dsn { namespace tools { @@ -45,7 +47,7 @@ uint64_t sim_env_provider::now_ns() const { return scheduler::instance().now_ns( void sim_env_provider::on_worker_start(task_worker *worker) { - set_thread_local_random_seed( + rand::set_seed_thread_local_rng( (_seed + worker->index() + worker->index() * worker->pool_spec().pool_code) ^ worker->index()); } @@ -65,5 +67,6 @@ sim_env_provider::sim_env_provider(env_provider *inner_provider) : env_provider( derror("simulation.random seed for this round is %d", _seed); } -} -} // end namespace + +} // namespace tools +} // namespace dsn diff --git a/src/core/tools/simulator/scheduler.cpp b/src/core/tools/simulator/scheduler.cpp index fa0d967745..c3732ceaa3 100644 --- a/src/core/tools/simulator/scheduler.cpp +++ b/src/core/tools/simulator/scheduler.cpp @@ -248,7 +248,7 @@ void scheduler::schedule() } if (ready_workers.size() > 0) { - int i = dsn_random32(0, (uint32_t)ready_workers.size() - 1); + int i = rand::uint32in(0, (uint32_t)ready_workers.size() - 1); _running_thread = _threads[ready_workers[i]]; _running_thread->runnable.release(); @@ -267,7 +267,7 @@ void scheduler::schedule() // randomize the events, and see std::random_shuffle( - events->begin(), events->end(), [](int n) { return dsn_random32(0, n - 1); }); + events->begin(), events->end(), [](int n) { return rand::uint32in(0, n - 1); }); for (auto e : *events) { if (e.app_task != nullptr) { diff --git a/src/core/tools/simulator/task_engine.sim.cpp b/src/core/tools/simulator/task_engine.sim.cpp index 6353e058e3..ad11521b4a 100644 --- a/src/core/tools/simulator/task_engine.sim.cpp +++ b/src/core/tools/simulator/task_engine.sim.cpp @@ -33,6 +33,7 @@ * xxxx-xx-xx, author, fix bug about xxx */ +#include #include "task_engine.sim.h" #include "scheduler.h" @@ -51,13 +52,13 @@ void sim_task_queue::enqueue(task *t) dassert(0 == t->delay_milliseconds(), "delay time must be zero"); if (_tasks.size() > 0) { do { - int random_pos = dsn_random32(0, 1000000); + int random_pos = rand::uint32in(0, 1000000); auto pr = _tasks.insert(std::map::value_type(random_pos, t)); if (pr.second) break; } while (true); } else { - int random_pos = dsn_random32(0, 1000000); + int random_pos = rand::uint32in(0, 1000000); _tasks.insert(std::map::value_type(random_pos, t)); } @@ -108,7 +109,7 @@ bool sim_semaphore_provider::wait(int timeout_milliseconds) } else { // wait success if (static_cast(timeout_milliseconds) == TIME_MS_MAX || - dsn_probability() <= 0.5) { + rand::float64n() <= 0.5) { _wait_threads.push_back(scheduler::task_worker_ext::get(task::get_current_worker())); scheduler::instance().wait_schedule(true, false); return true; diff --git a/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp b/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp index f4b24a9910..bff8a29e41 100644 --- a/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp +++ b/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp @@ -52,7 +52,7 @@ slave_failure_detector_with_multimaster::slave_failure_detector_with_multimaster } _meta_servers.group_address()->set_leader( - meta_servers[dsn_random32(0, (uint32_t)meta_servers.size() - 1)]); + meta_servers[rand::uint32in(0, (uint32_t)meta_servers.size() - 1)]); // ATTENTION: here we disable dsn_group_set_update_leader_automatically to avoid // failure detecting logic is affected by rpc failure or rpc forwarding. diff --git a/src/dist/replication/lib/replica.cpp b/src/dist/replication/lib/replica.cpp index 57045bd799..4413af3944 100644 --- a/src/dist/replication/lib/replica.cpp +++ b/src/dist/replication/lib/replica.cpp @@ -84,7 +84,7 @@ void replica::update_last_checkpoint_generate_time() uint64_t max_interval_ms = _options->checkpoint_max_interval_hours * 3600000UL; // use random trigger time to avoid flush peek _next_checkpoint_interval_trigger_time_ms = - _last_checkpoint_generate_time_ms + dsn_random64(max_interval_ms / 2, max_interval_ms); + _last_checkpoint_generate_time_ms + rand::uint64in(max_interval_ms / 2, max_interval_ms); } void replica::update_commit_statistics(int count) diff --git a/src/dist/replication/lib/replica_stub.cpp b/src/dist/replication/lib/replica_stub.cpp index cafc7f90c6..4459f6e170 100644 --- a/src/dist/replication/lib/replica_stub.cpp +++ b/src/dist/replication/lib/replica_stub.cpp @@ -536,7 +536,7 @@ void replica_stub::initialize(const replication_options &opts, bool clear /* = f [this] { on_gc(); }, std::chrono::milliseconds(_options.gc_interval_ms), 0, - std::chrono::milliseconds(dsn_random32(0, _options.gc_interval_ms))); + std::chrono::milliseconds(rand::uint32in(0, _options.gc_interval_ms))); } // disk stat @@ -1467,7 +1467,7 @@ void replica_stub::on_gc() kv.second.rep->tracker(), std::bind(&replica_stub::trigger_checkpoint, this, kv.second.rep, true), kv.first.thread_hash(), - std::chrono::milliseconds(dsn_random32(0, _options.gc_interval_ms / 2))); + std::chrono::milliseconds(rand::uint32in(0, _options.gc_interval_ms / 2))); } } else if (reserved_log_count > _options.log_shared_file_count_limit) { std::ostringstream oss; @@ -1493,7 +1493,7 @@ void replica_stub::on_gc() find->second.rep->tracker(), std::bind(&replica_stub::trigger_checkpoint, this, find->second.rep, true), id.thread_hash(), - std::chrono::milliseconds(dsn_random32(0, _options.gc_interval_ms / 2))); + std::chrono::milliseconds(rand::uint32in(0, _options.gc_interval_ms / 2))); } } } diff --git a/src/dist/replication/test/meta_test/misc/misc.cpp b/src/dist/replication/test/meta_test/misc/misc.cpp index 8cc45355b1..1693bb56b6 100644 --- a/src/dist/replication/test/meta_test/misc/misc.cpp +++ b/src/dist/replication/test/meta_test/misc/misc.cpp @@ -103,12 +103,12 @@ void generate_app_serving_replica_info(/*out*/ std::shared_ptrpartitions[i]; replica_info ri; - snprintf(buffer, 256, "disk%u", dsn_random32(1, total_disks)); + snprintf(buffer, 256, "disk%u", rand::uint32in(1, total_disks)); ri.disk_tag = buffer; cc.collect_serving_replica(pc.primary, ri); for (const dsn::rpc_address &addr : pc.secondaries) { - snprintf(buffer, 256, "disk%u", dsn_random32(1, total_disks)); + snprintf(buffer, 256, "disk%u", rand::uint32in(1, total_disks)); ri.disk_tag = buffer; cc.collect_serving_replica(addr, ri); } diff --git a/src/tests/dsn/fds_service_test.cpp b/src/tests/dsn/fds_service_test.cpp index 70e270800c..a80a08386c 100644 --- a/src/tests/dsn/fds_service_test.cpp +++ b/src/tests/dsn/fds_service_test.cpp @@ -82,7 +82,7 @@ void FDSClientTest::SetUp() // generate a test file { - int lines = dsn_random32(1000, 2000); + int lines = rand::uint32in(1000, 2000); FILE *fp = fopen(f1.filename.c_str(), "wb"); for (int i = 0; i < lines; ++i) { fprintf(fp, "%04d_this_is_a_simple_test_file\n", i); @@ -98,7 +98,7 @@ void FDSClientTest::SetUp() // generate another test file { - int lines = dsn_random32(10, 20); + int lines = rand::uint32in(10, 20); FILE *fp = fopen(f2.filename.c_str(), "wb"); for (int i = 0; i < lines; ++i) { fprintf(fp, "%04d_this_is_a_simple_test_file\n", i); @@ -719,7 +719,7 @@ generate_file(const char *filename, unsigned long long file_size, char *block, u i += batch_size; for (int j = 0; j < batch_size; ++j) { - block[j] = (char)dsn_random32(0, 255); + block[j] = (char)rand::uint32in(0, 255); } write(fd, block, batch_size); } @@ -758,7 +758,7 @@ TEST_F(FDSClientTest, test_concurrent_upload_download) for (int i = 0; i < total_files; ++i) { char index[64]; snprintf(index, 64, "%04d", i); - unsigned long random_size = dsn_random64(min_size, max_size); + unsigned long random_size = rand::uint64in(min_size, max_size); std::string filename = "randomfile" + std::string(index); filenames.push_back(filename); filesize.push_back(random_size); From 25bee3ec0f34fba1d93f3acc4c3f1d293f1d4b76 Mon Sep 17 00:00:00 2001 From: neverchanje Date: Sat, 15 Sep 2018 20:50:55 +0800 Subject: [PATCH 02/11] fix header dependencies --- src/core/core/rpc_engine.cpp | 1 + src/core/core/task.cpp | 1 + src/core/tools/common/asio_net_provider.cpp | 2 ++ src/core/tools/common/network.sim.cpp | 1 + src/core/tools/simulator/scheduler.cpp | 1 + .../failure_detector_multimaster.cpp | 1 + src/dist/replication/lib/replica.cpp | 1 + src/dist/replication/lib/replica_stub.cpp | 1 + src/dist/replication/test/meta_test/misc/misc.cpp | 2 ++ src/tests/dsn/fds_service_test.cpp | 1 + 10 files changed, 12 insertions(+) diff --git a/src/core/core/rpc_engine.cpp b/src/core/core/rpc_engine.cpp index b8f3bd38b6..6bfe90beac 100644 --- a/src/core/core/rpc_engine.cpp +++ b/src/core/core/rpc_engine.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include namespace dsn { diff --git a/src/core/core/task.cpp b/src/core/core/task.cpp index 8e6709e60c..86bf7934fd 100644 --- a/src/core/core/task.cpp +++ b/src/core/core/task.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "task_engine.h" diff --git a/src/core/tools/common/asio_net_provider.cpp b/src/core/tools/common/asio_net_provider.cpp index 32f86a9866..b88a19fda0 100644 --- a/src/core/tools/common/asio_net_provider.cpp +++ b/src/core/tools/common/asio_net_provider.cpp @@ -33,6 +33,8 @@ * xxxx-xx-xx, author, fix bug about xxx */ +#include + #include "asio_net_provider.h" #include "asio_rpc_session.h" diff --git a/src/core/tools/common/network.sim.cpp b/src/core/tools/common/network.sim.cpp index d660f70f33..08c3558050 100644 --- a/src/core/tools/common/network.sim.cpp +++ b/src/core/tools/common/network.sim.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "network.sim.h" diff --git a/src/core/tools/simulator/scheduler.cpp b/src/core/tools/simulator/scheduler.cpp index c3732ceaa3..4054fde297 100644 --- a/src/core/tools/simulator/scheduler.cpp +++ b/src/core/tools/simulator/scheduler.cpp @@ -33,6 +33,7 @@ * xxxx-xx-xx, author, fix bug about xxx */ +#include #include #include #include diff --git a/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp b/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp index bff8a29e41..8d75ffd5f2 100644 --- a/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp +++ b/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp @@ -37,6 +37,7 @@ #include #include #include +#include namespace dsn { namespace dist { diff --git a/src/dist/replication/lib/replica.cpp b/src/dist/replication/lib/replica.cpp index 4413af3944..99884a53ff 100644 --- a/src/dist/replication/lib/replica.cpp +++ b/src/dist/replication/lib/replica.cpp @@ -32,6 +32,7 @@ #include #include #include +#include namespace dsn { namespace replication { diff --git a/src/dist/replication/lib/replica_stub.cpp b/src/dist/replication/lib/replica_stub.cpp index 4459f6e170..fe56e42620 100644 --- a/src/dist/replication/lib/replica_stub.cpp +++ b/src/dist/replication/lib/replica_stub.cpp @@ -39,6 +39,7 @@ #include "mutation.h" #include #include +#include #include #include #include diff --git a/src/dist/replication/test/meta_test/misc/misc.cpp b/src/dist/replication/test/meta_test/misc/misc.cpp index 1693bb56b6..cb57b43324 100644 --- a/src/dist/replication/test/meta_test/misc/misc.cpp +++ b/src/dist/replication/test/meta_test/misc/misc.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include "dist/replication/common/replication_common.h" #include "misc.h" diff --git a/src/tests/dsn/fds_service_test.cpp b/src/tests/dsn/fds_service_test.cpp index a80a08386c..8eb799b74c 100644 --- a/src/tests/dsn/fds_service_test.cpp +++ b/src/tests/dsn/fds_service_test.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include #include From 04942e3557afa2668a8a4493e9ce3304a756c873 Mon Sep 17 00:00:00 2001 From: neverchanje Date: Sat, 15 Sep 2018 20:53:34 +0800 Subject: [PATCH 03/11] fix dsn_random32 --- include/dsn/tool-api/group_address.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/dsn/tool-api/group_address.h b/include/dsn/tool-api/group_address.h index 8bc61fcaee..e7ee1e80ce 100644 --- a/include/dsn/tool-api/group_address.h +++ b/include/dsn/tool-api/group_address.h @@ -40,6 +40,7 @@ #include #include #include +#include #include namespace dsn { @@ -60,7 +61,7 @@ class rpc_group_address : public dsn::ref_counter { alr_t l(_lock); return _members.empty() ? rpc_address::s_invalid_address - : _members[dsn_random32(0, (uint32_t)_members.size() - 1)]; + : _members[rand::uint32in(0, (uint32_t)_members.size() - 1)]; } rpc_address next(rpc_address current) const; rpc_address leader() const @@ -158,7 +159,7 @@ inline rpc_address rpc_group_address::possible_leader() if (_members.empty()) return rpc_address::s_invalid_address; if (_leader_index == -1) - _leader_index = dsn_random32(0, (uint32_t)_members.size() - 1); + _leader_index = rand::uint32in(0, (uint32_t)_members.size() - 1); return _members[_leader_index]; } @@ -194,11 +195,11 @@ inline rpc_address rpc_group_address::next(rpc_address current) const if (_members.empty()) return rpc_address::s_invalid_address; if (current.is_invalid()) - return _members[dsn_random32(0, (uint32_t)_members.size() - 1)]; + return _members[rand::uint32in(0, (uint32_t)_members.size() - 1)]; else { auto it = std::find(_members.begin(), _members.end(), current); if (it == _members.end()) - return _members[dsn_random32(0, (uint32_t)_members.size() - 1)]; + return _members[rand::uint32in(0, (uint32_t)_members.size() - 1)]; else { it++; return it == _members.end() ? _members[0] : *it; From 645f30b1016db9d1381f35a5757c5b4a5d39f1c8 Mon Sep 17 00:00:00 2001 From: neverchanje Date: Sat, 15 Sep 2018 20:59:46 +0800 Subject: [PATCH 04/11] fix compilation errors --- src/core/core/partition_resolver_simple.cpp | 1 + src/core/core/rand.cc | 2 -- src/core/core/service_api_c.cpp | 11 +++++++++++ src/dist/replication/test/meta_test/misc/misc.cpp | 4 ++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/core/core/partition_resolver_simple.cpp b/src/core/core/partition_resolver_simple.cpp index 03048a7468..86982312f1 100644 --- a/src/core/core/partition_resolver_simple.cpp +++ b/src/core/core/partition_resolver_simple.cpp @@ -35,6 +35,7 @@ #include "partition_resolver_simple.h" #include +#include #include namespace dsn { diff --git a/src/core/core/rand.cc b/src/core/core/rand.cc index c4a9908c2f..129b9095be 100644 --- a/src/core/core/rand.cc +++ b/src/core/core/rand.cc @@ -2,8 +2,6 @@ // This source code is licensed under the Apache License Version 2.0, which // can be found in the LICENSE file in the root directory of this source tree. -#pragma once - #include #include diff --git a/src/core/core/service_api_c.cpp b/src/core/core/service_api_c.cpp index 3426ae9f98..7ad322bf47 100644 --- a/src/core/core/service_api_c.cpp +++ b/src/core/core/service_api_c.cpp @@ -370,6 +370,17 @@ DSN_API void dsn_file_write_vector(dsn_handle_t file, ::dsn::task::get_current_disk()->write(cb); } +//------------------------------------------------------------------------------ +// +// env +// +//------------------------------------------------------------------------------ +DSN_API uint64_t dsn_now_ns() +{ + // return ::dsn::task::get_current_env()->now_ns(); + return ::dsn::service_engine::instance().env()->now_ns(); +} + static uint64_t s_runtime_init_time_ms; DSN_API uint64_t dsn_runtime_init_time_ms() { return s_runtime_init_time_ms; } diff --git a/src/dist/replication/test/meta_test/misc/misc.cpp b/src/dist/replication/test/meta_test/misc/misc.cpp index cb57b43324..6141cbbe63 100644 --- a/src/dist/replication/test/meta_test/misc/misc.cpp +++ b/src/dist/replication/test/meta_test/misc/misc.cpp @@ -105,12 +105,12 @@ void generate_app_serving_replica_info(/*out*/ std::shared_ptrpartitions[i]; replica_info ri; - snprintf(buffer, 256, "disk%u", rand::uint32in(1, total_disks)); + snprintf(buffer, 256, "disk%u", dsn::rand::uint32in(1, total_disks)); ri.disk_tag = buffer; cc.collect_serving_replica(pc.primary, ri); for (const dsn::rpc_address &addr : pc.secondaries) { - snprintf(buffer, 256, "disk%u", rand::uint32in(1, total_disks)); + snprintf(buffer, 256, "disk%u", dsn::rand::uint32in(1, total_disks)); ri.disk_tag = buffer; cc.collect_serving_replica(addr, ri); } From e205f809c78ad401b3a5211361c6110a762ce65d Mon Sep 17 00:00:00 2001 From: neverchanje Date: Thu, 20 Sep 2018 12:16:01 +0800 Subject: [PATCH 05/11] fix comment --- include/dsn/utility/rand.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/include/dsn/utility/rand.h b/include/dsn/utility/rand.h index fc594fe535..96c2b70dec 100644 --- a/include/dsn/utility/rand.h +++ b/include/dsn/utility/rand.h @@ -10,19 +10,22 @@ namespace dsn { namespace rand { -// uint64n returns, as an uint64_t, a non-negative pseudo-random number in [min, max). +// uint64n returns, as an uint64_t, a non-negative pseudo-random number in [min, max]. extern uint64_t uint64in(uint64_t min, uint64_t max); -// uint64n returns, as an uint64_t, a non-negative pseudo-random number in [0, n). -inline uint64_t uint64n(uint64_t n) { return uint64in(0, n - 1); } +// uint64n returns, as an uint64_t, a non-negative pseudo-random number in [0, n]. +inline uint64_t uint64n(uint64_t n) { return uint64in(0, n); } -// uint32n returns, as an uint32_t, a non-negative pseudo-random number in [0, n). +// uint32n returns, as an uint32_t, a non-negative pseudo-random number in [0, n]. inline uint32_t uint32n(uint32_t n) { return static_cast(uint64n(n)); } -// uint32n returns, as an uint32_t, a non-negative pseudo-random number in [min, max). -inline uint32_t uint32in(uint32_t min, uint32_t max) { return uint32n(max - min) + min; } +// uint32n returns, as an uint32_t, a non-negative pseudo-random number in [min, max]. +inline uint32_t uint32in(uint32_t min, uint32_t max) +{ + return static_cast(uint64in(min, max)); +} -// float64 returns, as a double, a pseudo-random number in [0.0,1.0). +// float64 returns, as a double, a pseudo-random number in [0.0,1.0]. inline double float64n() { return uint64n(1000000000) / 1000000000.0; } extern void set_seed_thread_local_rng(uint64_t seed); From f1d6b835b69043a7ead365d1259af713f20173b7 Mon Sep 17 00:00:00 2001 From: neverchanje Date: Thu, 20 Sep 2018 15:54:05 +0800 Subject: [PATCH 06/11] add refactoring and fixes --- include/dsn/utility/rand.h | 19 ++++++--- src/core/core/env_provider.cpp | 2 - src/core/core/rand.cc | 2 +- src/core/tests/rand_test.cpp | 71 ++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 src/core/tests/rand_test.cpp diff --git a/include/dsn/utility/rand.h b/include/dsn/utility/rand.h index 96c2b70dec..10b8fe297f 100644 --- a/include/dsn/utility/rand.h +++ b/include/dsn/utility/rand.h @@ -6,6 +6,7 @@ #include #include +#include namespace dsn { namespace rand { @@ -13,18 +14,24 @@ namespace rand { // uint64n returns, as an uint64_t, a non-negative pseudo-random number in [min, max]. extern uint64_t uint64in(uint64_t min, uint64_t max); -// uint64n returns, as an uint64_t, a non-negative pseudo-random number in [0, n]. -inline uint64_t uint64n(uint64_t n) { return uint64in(0, n); } - -// uint32n returns, as an uint32_t, a non-negative pseudo-random number in [0, n]. -inline uint32_t uint32n(uint32_t n) { return static_cast(uint64n(n)); } - // uint32n returns, as an uint32_t, a non-negative pseudo-random number in [min, max]. inline uint32_t uint32in(uint32_t min, uint32_t max) { return static_cast(uint64in(min, max)); } +// uint64n returns, as an uint64_t, a non-negative pseudo-random number in [0, n). +inline uint64_t uint64n(uint64_t n) { return uint64in(0, n - 1); } + +// uint32n returns, as an uint32_t, a non-negative pseudo-random number in [0, n). +inline uint32_t uint32n(uint32_t n) { return static_cast(uint64n(n)); } + +// uint32 returns a pseudo-random 32-bit value as a uint32_t. +inline uint32_t uint32() { return uint32n(std::numeric_limits::max()); } + +// uint64 returns a pseudo-random 64-bit value as a uint64_t. +inline uint64_t uint64() { return uint64n(std::numeric_limits::max()); } + // float64 returns, as a double, a pseudo-random number in [0.0,1.0]. inline double float64n() { return uint64n(1000000000) / 1000000000.0; } diff --git a/src/core/core/env_provider.cpp b/src/core/core/env_provider.cpp index 3ed2e6923b..237e112303 100644 --- a/src/core/core/env_provider.cpp +++ b/src/core/core/env_provider.cpp @@ -41,8 +41,6 @@ namespace dsn { //------------ env_provider --------------- -__thread unsigned int env_provider__tls_magic; -__thread std::ranlux48_base *env_provider__rng; env_provider::env_provider(env_provider *inner_provider) {} diff --git a/src/core/core/rand.cc b/src/core/core/rand.cc index 129b9095be..f8efff7be5 100644 --- a/src/core/core/rand.cc +++ b/src/core/core/rand.cc @@ -8,7 +8,7 @@ namespace dsn { namespace rand { -thread_local std::ranlux48_base g_thread_local_rng; +thread_local std::ranlux48_base g_thread_local_rng(std::random_device{}()); /*extern*/ uint64_t uint64in(uint64_t min, uint64_t max) { diff --git a/src/core/tests/rand_test.cpp b/src/core/tests/rand_test.cpp new file mode 100644 index 0000000000..80927bc411 --- /dev/null +++ b/src/core/tests/rand_test.cpp @@ -0,0 +1,71 @@ +// Copyright (c) 2017, Xiaomi, Inc. All rights reserved. +// This source code is licensed under the Apache License Version 2.0, which +// can be found in the LICENSE file in the root directory of this source tree. + +#include +#include +#include + +namespace dsn { + +TEST(random, sanity) +{ + { // edge cases + ASSERT_EQ(rand::uint64n(0), 0); + ASSERT_EQ(rand::uint64in(0, 0), 0); + ASSERT_EQ(rand::uint32n(0), 0); + ASSERT_EQ(rand::uint32in(0, 0), 0); + + ASSERT_EQ(rand::uint64n(12), 12); + ASSERT_EQ(rand::uint64in(12, 12), 12); + ASSERT_EQ(rand::uint32n(12), 12); + ASSERT_EQ(rand::uint32in(12, 12), 12); + } + + constexpr int kTestSize = 1000; + + { // 32-bit repeatability, uniqueness + rand::set_seed_thread_local_rng(0xdeadbeef); + std::vector vals(kTestSize); + for (int i = 0; i < kTestSize; ++i) { + vals[i] = rand::uint32(); + } + + rand::set_seed_thread_local_rng(0xdeadbeef); + for (int i = 0; i < kTestSize; ++i) { + ASSERT_EQ(rand::uint32(), vals[i]); + } + } + + { // 64-bit repeatability, uniqueness + rand::set_seed_thread_local_rng(0xdeadbeef); + std::vector vals(kTestSize); + for (int i = 0; i < kTestSize; ++i) { + vals[i] = rand::uint64(); + } + + rand::set_seed_thread_local_rng(0xdeadbeef); + for (int i = 0; i < kTestSize; ++i) { + ASSERT_EQ(rand::uint64(), vals[i]); + } + } +} + +TEST(random, multi_threaded) +{ + const int n = 100; + std::vector seeds(n); + std::vector threads; + for (int i = 0; i < n; ++i) { + threads.push_back(std::thread([i, &seeds] { seeds[i] = rand::uint32(); })); + } + for (auto &t : threads) { + t.join(); + } + std::sort(seeds.begin(), seeds.end()); + for (int i = 0; i < n - 1; ++i) { + EXPECT_LT(seeds[i], seeds[i + 1]); + } +} + +} // namespace dsn From 43bd11d2f28526ec70e4b0e20375476e99ec5505 Mon Sep 17 00:00:00 2001 From: neverchanje Date: Thu, 20 Sep 2018 16:10:52 +0800 Subject: [PATCH 07/11] minor fixes --- include/dsn/utility/rand.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/dsn/utility/rand.h b/include/dsn/utility/rand.h index 10b8fe297f..bbc135dd88 100644 --- a/include/dsn/utility/rand.h +++ b/include/dsn/utility/rand.h @@ -27,13 +27,13 @@ inline uint64_t uint64n(uint64_t n) { return uint64in(0, n - 1); } inline uint32_t uint32n(uint32_t n) { return static_cast(uint64n(n)); } // uint32 returns a pseudo-random 32-bit value as a uint32_t. -inline uint32_t uint32() { return uint32n(std::numeric_limits::max()); } +inline uint32_t uint32() { return uint32in(0, std::numeric_limits::max()); } // uint64 returns a pseudo-random 64-bit value as a uint64_t. -inline uint64_t uint64() { return uint64n(std::numeric_limits::max()); } +inline uint64_t uint64() { return uint64in(0, std::numeric_limits::max()); } // float64 returns, as a double, a pseudo-random number in [0.0,1.0]. -inline double float64n() { return uint64n(1000000000) / 1000000000.0; } +inline double float64n() { return uint64in(0, 1000000000) / 1000000000.0; } extern void set_seed_thread_local_rng(uint64_t seed); From 2eaa16dfe884f0f0b39aa3c8dfa52c1ae640ff4b Mon Sep 17 00:00:00 2001 From: neverchanje Date: Thu, 20 Sep 2018 16:37:03 +0800 Subject: [PATCH 08/11] fix corner case --- include/dsn/utility/rand.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/dsn/utility/rand.h b/include/dsn/utility/rand.h index bbc135dd88..fdb74dd1d3 100644 --- a/include/dsn/utility/rand.h +++ b/include/dsn/utility/rand.h @@ -21,9 +21,16 @@ inline uint32_t uint32in(uint32_t min, uint32_t max) } // uint64n returns, as an uint64_t, a non-negative pseudo-random number in [0, n). -inline uint64_t uint64n(uint64_t n) { return uint64in(0, n - 1); } +// If n == 0, it returns 0. +inline uint64_t uint64n(uint64_t n) +{ + if (n == 0) + return 0; + return uint64in(0, n - 1); +} // uint32n returns, as an uint32_t, a non-negative pseudo-random number in [0, n). +// If n == 0, it returns 0. inline uint32_t uint32n(uint32_t n) { return static_cast(uint64n(n)); } // uint32 returns a pseudo-random 32-bit value as a uint32_t. From b691fcfb49c758d74cbb5f8f5076c07c31a5cbc4 Mon Sep 17 00:00:00 2001 From: neverchanje Date: Thu, 20 Sep 2018 16:42:17 +0800 Subject: [PATCH 09/11] fix test --- src/core/tests/rand_test.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/tests/rand_test.cpp b/src/core/tests/rand_test.cpp index 80927bc411..e6cffafb46 100644 --- a/src/core/tests/rand_test.cpp +++ b/src/core/tests/rand_test.cpp @@ -16,9 +16,7 @@ TEST(random, sanity) ASSERT_EQ(rand::uint32n(0), 0); ASSERT_EQ(rand::uint32in(0, 0), 0); - ASSERT_EQ(rand::uint64n(12), 12); ASSERT_EQ(rand::uint64in(12, 12), 12); - ASSERT_EQ(rand::uint32n(12), 12); ASSERT_EQ(rand::uint32in(12, 12), 12); } From 214bcafc34b1ecec5e4e3fa812d9fc1de626af0a Mon Sep 17 00:00:00 2001 From: neverchanje Date: Fri, 21 Sep 2018 10:57:32 +0800 Subject: [PATCH 10/11] code refactoring --- include/dsn/utility/rand.h | 47 +++++++++++--------- src/core/core/{rand.cc => rand.cpp} | 4 +- src/core/core/rpc_engine.cpp | 4 +- src/core/tests/env.cpp | 4 +- src/core/tests/rand_test.cpp | 26 +++++------ src/core/tests/service_api_c.cpp | 2 +- src/core/tools/common/asio_net_provider.cpp | 4 +- src/core/tools/common/fault_injector.cpp | 16 +++---- src/core/tools/simulator/env.sim.cpp | 6 +-- src/core/tools/simulator/task_engine.sim.cpp | 2 +- src/dist/replication/lib/replica.cpp | 2 +- src/tests/dsn/fds_service_test.cpp | 2 +- 12 files changed, 62 insertions(+), 57 deletions(-) rename src/core/core/{rand.cc => rand.cpp} (77%) diff --git a/include/dsn/utility/rand.h b/include/dsn/utility/rand.h index fdb74dd1d3..5c4d7e3e35 100644 --- a/include/dsn/utility/rand.h +++ b/include/dsn/utility/rand.h @@ -11,38 +11,43 @@ namespace dsn { namespace rand { -// uint64n returns, as an uint64_t, a non-negative pseudo-random number in [min, max]. -extern uint64_t uint64in(uint64_t min, uint64_t max); +/// This package offers several functions for random number generation. +/// It is guaranteed to be thread-safe by using a PRNG with one instance per thread. +/// By default, the RNG is seeded from std::random_device. -// uint32n returns, as an uint32_t, a non-negative pseudo-random number in [min, max]. -inline uint32_t uint32in(uint32_t min, uint32_t max) -{ - return static_cast(uint64in(min, max)); -} +/// \returns, as an uint64_t, a non-negative pseudo-random number in [min, max]. +extern uint64_t next_u64(uint64_t min, uint64_t max); -// uint64n returns, as an uint64_t, a non-negative pseudo-random number in [0, n). -// If n == 0, it returns 0. -inline uint64_t uint64n(uint64_t n) +/// \returns, as an uint64_t, a non-negative pseudo-random number in [0, n). +/// If n == 0, it returns 0. +inline uint64_t next_u64(uint64_t n) { if (n == 0) return 0; - return uint64in(0, n - 1); + return next_u64(0, n - 1); } -// uint32n returns, as an uint32_t, a non-negative pseudo-random number in [0, n). -// If n == 0, it returns 0. -inline uint32_t uint32n(uint32_t n) { return static_cast(uint64n(n)); } +/// \returns a pseudo-random 64-bit value as a uint64_t. +inline uint64_t next_u64() { return next_u64(0, std::numeric_limits::max()); } + +/// \returns, as an uint32_t, a non-negative pseudo-random number in [min, max]. +inline uint32_t next_u32(uint32_t min, uint32_t max) +{ + return static_cast(next_u64(min, max)); +} -// uint32 returns a pseudo-random 32-bit value as a uint32_t. -inline uint32_t uint32() { return uint32in(0, std::numeric_limits::max()); } +/// \returns, as an uint32_t, a non-negative pseudo-random number in [0, n). +/// If n == 0, it returns 0. +inline uint32_t next_u32(uint32_t n) { return static_cast(next_u64(n)); } -// uint64 returns a pseudo-random 64-bit value as a uint64_t. -inline uint64_t uint64() { return uint64in(0, std::numeric_limits::max()); } +/// \returns a pseudo-random 32-bit value as a uint32_t. +inline uint32_t next_u32() { return next_u32(0, std::numeric_limits::max()); } -// float64 returns, as a double, a pseudo-random number in [0.0,1.0]. -inline double float64n() { return uint64in(0, 1000000000) / 1000000000.0; } +/// \returns, as a double, a pseudo-random number in [0.0,1.0]. +inline double next_double01() { return next_u64(0, 1000000000) / 1000000000.0; } -extern void set_seed_thread_local_rng(uint64_t seed); +/// Reseeds the RNG of current thread. +extern void reseed_thread_local_rng(uint64_t seed); } // namespace rand } // namespace dsn diff --git a/src/core/core/rand.cc b/src/core/core/rand.cpp similarity index 77% rename from src/core/core/rand.cc rename to src/core/core/rand.cpp index f8efff7be5..095d1038d4 100644 --- a/src/core/core/rand.cc +++ b/src/core/core/rand.cpp @@ -10,12 +10,12 @@ namespace rand { thread_local std::ranlux48_base g_thread_local_rng(std::random_device{}()); -/*extern*/ uint64_t uint64in(uint64_t min, uint64_t max) +/*extern*/ uint64_t next_u64(uint64_t min, uint64_t max) { return std::uniform_int_distribution(min, max)(g_thread_local_rng); } -/*extern*/ void set_seed_thread_local_rng(uint64_t seed) { g_thread_local_rng.seed(seed); } +/*extern*/ void reseed_thread_local_rng(uint64_t seed) { g_thread_local_rng.seed(seed); } } // namespace rand } // namespace dsn diff --git a/src/core/core/rpc_engine.cpp b/src/core/core/rpc_engine.cpp index 6bfe90beac..e46f1ae34c 100644 --- a/src/core/core/rpc_engine.cpp +++ b/src/core/core/rpc_engine.cpp @@ -635,8 +635,8 @@ void rpc_engine::call(message_ex *request, const rpc_response_task_ptr &call) { auto &hdr = *request->header; hdr.from_address = primary_address(); - hdr.trace_id = rand::uint64in(std::numeric_limits::min(), - std::numeric_limits::max()); + hdr.trace_id = rand::next_u64(std::numeric_limits::min(), + std::numeric_limits::max()); call_address(request->server_address, request, call); } diff --git a/src/core/tests/env.cpp b/src/core/tests/env.cpp index f0d6271bf3..a4fe991134 100644 --- a/src/core/tests/env.cpp +++ b/src/core/tests/env.cpp @@ -45,10 +45,10 @@ TEST(core, env) uint64_t xs[] = {0, std::numeric_limits::max() - 1, 0xdeadbeef}; for (auto &x : xs) { - auto r = rand::uint64in(x, x); + auto r = rand::next_u64(x, x); EXPECT_EQ(r, x); - r = rand::uint64in(x, x + 1); + r = rand::next_u64(x, x + 1); EXPECT_TRUE(r == x || r == (x + 1)); } } diff --git a/src/core/tests/rand_test.cpp b/src/core/tests/rand_test.cpp index e6cffafb46..88804d8a33 100644 --- a/src/core/tests/rand_test.cpp +++ b/src/core/tests/rand_test.cpp @@ -11,40 +11,40 @@ namespace dsn { TEST(random, sanity) { { // edge cases - ASSERT_EQ(rand::uint64n(0), 0); - ASSERT_EQ(rand::uint64in(0, 0), 0); - ASSERT_EQ(rand::uint32n(0), 0); + ASSERT_EQ(rand::next_u64(0), 0); + ASSERT_EQ(rand::next_u64(0, 0), 0); + ASSERT_EQ(rand::next_u32(0), 0); ASSERT_EQ(rand::uint32in(0, 0), 0); - ASSERT_EQ(rand::uint64in(12, 12), 12); + ASSERT_EQ(rand::next_u64(12, 12), 12); ASSERT_EQ(rand::uint32in(12, 12), 12); } constexpr int kTestSize = 1000; { // 32-bit repeatability, uniqueness - rand::set_seed_thread_local_rng(0xdeadbeef); + rand::reseed_thread_local_rng(0xdeadbeef); std::vector vals(kTestSize); for (int i = 0; i < kTestSize; ++i) { - vals[i] = rand::uint32(); + vals[i] = rand::next_u32(); } - rand::set_seed_thread_local_rng(0xdeadbeef); + rand::reseed_thread_local_rng(0xdeadbeef); for (int i = 0; i < kTestSize; ++i) { - ASSERT_EQ(rand::uint32(), vals[i]); + ASSERT_EQ(rand::next_u32(), vals[i]); } } { // 64-bit repeatability, uniqueness - rand::set_seed_thread_local_rng(0xdeadbeef); + rand::reseed_thread_local_rng(0xdeadbeef); std::vector vals(kTestSize); for (int i = 0; i < kTestSize; ++i) { - vals[i] = rand::uint64(); + vals[i] = rand::next_u64(); } - rand::set_seed_thread_local_rng(0xdeadbeef); + rand::reseed_thread_local_rng(0xdeadbeef); for (int i = 0; i < kTestSize; ++i) { - ASSERT_EQ(rand::uint64(), vals[i]); + ASSERT_EQ(rand::next_u64(), vals[i]); } } } @@ -55,7 +55,7 @@ TEST(random, multi_threaded) std::vector seeds(n); std::vector threads; for (int i = 0; i < n; ++i) { - threads.push_back(std::thread([i, &seeds] { seeds[i] = rand::uint32(); })); + threads.push_back(std::thread([i, &seeds] { seeds[i] = rand::next_u32(); })); } for (auto &t : threads) { t.join(); diff --git a/src/core/tests/service_api_c.cpp b/src/core/tests/service_api_c.cpp index 743b28868d..ba9139a72d 100644 --- a/src/core/tests/service_api_c.cpp +++ b/src/core/tests/service_api_c.cpp @@ -289,7 +289,7 @@ TEST(core, dsn_env) std::this_thread::sleep_for(std::chrono::milliseconds(1)); uint64_t now2 = dsn_now_ns(); ASSERT_LE(now1 + 1000000, now2); - uint64_t r = rand::uint64in(100, 200); + uint64_t r = rand::next_u64(100, 200); ASSERT_LE(100, r); ASSERT_GE(200, r); } diff --git a/src/core/tools/common/asio_net_provider.cpp b/src/core/tools/common/asio_net_provider.cpp index b88a19fda0..8eb508e995 100644 --- a/src/core/tools/common/asio_net_provider.cpp +++ b/src/core/tools/common/asio_net_provider.cpp @@ -295,8 +295,8 @@ error_code asio_udp_provider::start(rpc_channel channel, int port, bool client_o // refactored _address.assign_ipv4(get_local_ipv4(), std::numeric_limits::max() - - rand::uint64in(std::numeric_limits::min(), - std::numeric_limits::max()) % + rand::next_u64(std::numeric_limits::min(), + std::numeric_limits::max()) % 5000); ::boost::asio::ip::udp::endpoint endpoint(boost::asio::ip::address_v4::any(), _address.port()); diff --git a/src/core/tools/common/fault_injector.cpp b/src/core/tools/common/fault_injector.cpp index e948554a4a..21956b07e1 100644 --- a/src/core/tools/common/fault_injector.cpp +++ b/src/core/tools/common/fault_injector.cpp @@ -163,14 +163,14 @@ static bool fault_on_aio_call(task *caller, aio_task *callee) { switch (callee->aio()->type) { case AIO_Read: - if (rand::float64n() < s_fj_opts[callee->spec().code].disk_read_fail_ratio) { + if (rand::next_double01() < s_fj_opts[callee->spec().code].disk_read_fail_ratio) { ddebug("fault inject %s at %s", callee->spec().name.c_str(), __FUNCTION__); callee->set_error_code(ERR_FILE_OPERATION_FAILED); return false; } break; case AIO_Write: - if (rand::float64n() < s_fj_opts[callee->spec().code].disk_write_fail_ratio) { + if (rand::next_double01() < s_fj_opts[callee->spec().code].disk_write_fail_ratio) { ddebug("fault inject %s at %s", callee->spec().name.c_str(), __FUNCTION__); callee->set_error_code(ERR_FILE_OPERATION_FAILED); return false; @@ -226,7 +226,7 @@ static void corrupt_data(message_ex *request, const std::string &corrupt_type) static bool fault_on_rpc_call(task *caller, message_ex *req, rpc_response_task *callee) { fj_opt &opt = s_fj_opts[req->local_rpc_code]; - if (rand::float64n() < opt.rpc_request_drop_ratio) { + if (rand::next_double01() < opt.rpc_request_drop_ratio) { ddebug("fault inject %s at %s: %s => %s", req->header->rpc_name, __FUNCTION__, @@ -234,7 +234,7 @@ static bool fault_on_rpc_call(task *caller, message_ex *req, rpc_response_task * req->to_address.to_string()); return false; } else { - if (rand::float64n() < opt.rpc_request_data_corrupted_ratio) { + if (rand::next_double01() < opt.rpc_request_data_corrupted_ratio) { ddebug("corrupt the rpc call message from: %s, type: %s", req->header->from_address.to_string(), opt.rpc_message_data_corrupted_type.c_str()); @@ -248,7 +248,7 @@ static void fault_on_rpc_request_enqueue(rpc_request_task *callee) { fj_opt &opt = s_fj_opts[callee->spec().code]; if (callee->delay_milliseconds() == 0 && task_ext_for_fj::get(callee) == 0) { - if (rand::float64n() < opt.rpc_request_delay_ratio) { + if (rand::next_double01() < opt.rpc_request_delay_ratio) { callee->set_delay( rand::uint32in(opt.rpc_message_delay_ms_min, opt.rpc_message_delay_ms_max)); ddebug("fault inject %s at %s with delay %u ms", @@ -264,7 +264,7 @@ static void fault_on_rpc_request_enqueue(rpc_request_task *callee) static bool fault_on_rpc_reply(task *caller, message_ex *msg) { fj_opt &opt = s_fj_opts[msg->local_rpc_code]; - if (rand::float64n() < opt.rpc_response_drop_ratio) { + if (rand::next_double01() < opt.rpc_response_drop_ratio) { ddebug("fault inject %s at %s: %s => %s", msg->header->rpc_name, __FUNCTION__, @@ -272,7 +272,7 @@ static bool fault_on_rpc_reply(task *caller, message_ex *msg) msg->to_address.to_string()); return false; } else { - if (rand::float64n() < opt.rpc_response_data_corrupted_ratio) { + if (rand::next_double01() < opt.rpc_response_data_corrupted_ratio) { ddebug("fault injector corrupt the rpc reply message from: %s, type: %s", msg->header->from_address.to_string(), opt.rpc_message_data_corrupted_type.c_str()); @@ -286,7 +286,7 @@ static void fault_on_rpc_response_enqueue(rpc_response_task *resp) { fj_opt &opt = s_fj_opts[resp->spec().code]; if (resp->delay_milliseconds() == 0 && task_ext_for_fj::get(resp) == 0) { - if (rand::float64n() < opt.rpc_response_delay_ratio) { + if (rand::next_double01() < opt.rpc_response_delay_ratio) { resp->set_delay( rand::uint32in(opt.rpc_message_delay_ms_min, opt.rpc_message_delay_ms_max)); ddebug("fault inject %s at %s with delay %u ms", diff --git a/src/core/tools/simulator/env.sim.cpp b/src/core/tools/simulator/env.sim.cpp index 2dccb48a5c..ac92b0f6a7 100644 --- a/src/core/tools/simulator/env.sim.cpp +++ b/src/core/tools/simulator/env.sim.cpp @@ -47,9 +47,9 @@ uint64_t sim_env_provider::now_ns() const { return scheduler::instance().now_ns( void sim_env_provider::on_worker_start(task_worker *worker) { - rand::set_seed_thread_local_rng( - (_seed + worker->index() + worker->index() * worker->pool_spec().pool_code) ^ - worker->index()); + rand::reseed_thread_local_rng( + (_seed + worker->index() + worker->index() * worker->pool_spec().pool_code) ^ + worker->index()); } sim_env_provider::sim_env_provider(env_provider *inner_provider) : env_provider(inner_provider) diff --git a/src/core/tools/simulator/task_engine.sim.cpp b/src/core/tools/simulator/task_engine.sim.cpp index ad11521b4a..ed2254ec23 100644 --- a/src/core/tools/simulator/task_engine.sim.cpp +++ b/src/core/tools/simulator/task_engine.sim.cpp @@ -109,7 +109,7 @@ bool sim_semaphore_provider::wait(int timeout_milliseconds) } else { // wait success if (static_cast(timeout_milliseconds) == TIME_MS_MAX || - rand::float64n() <= 0.5) { + rand::next_double01() <= 0.5) { _wait_threads.push_back(scheduler::task_worker_ext::get(task::get_current_worker())); scheduler::instance().wait_schedule(true, false); return true; diff --git a/src/dist/replication/lib/replica.cpp b/src/dist/replication/lib/replica.cpp index 99884a53ff..d71040ba24 100644 --- a/src/dist/replication/lib/replica.cpp +++ b/src/dist/replication/lib/replica.cpp @@ -85,7 +85,7 @@ void replica::update_last_checkpoint_generate_time() uint64_t max_interval_ms = _options->checkpoint_max_interval_hours * 3600000UL; // use random trigger time to avoid flush peek _next_checkpoint_interval_trigger_time_ms = - _last_checkpoint_generate_time_ms + rand::uint64in(max_interval_ms / 2, max_interval_ms); + _last_checkpoint_generate_time_ms + rand::next_u64(max_interval_ms / 2, max_interval_ms); } void replica::update_commit_statistics(int count) diff --git a/src/tests/dsn/fds_service_test.cpp b/src/tests/dsn/fds_service_test.cpp index 8eb799b74c..6a6fe7fe38 100644 --- a/src/tests/dsn/fds_service_test.cpp +++ b/src/tests/dsn/fds_service_test.cpp @@ -759,7 +759,7 @@ TEST_F(FDSClientTest, test_concurrent_upload_download) for (int i = 0; i < total_files; ++i) { char index[64]; snprintf(index, 64, "%04d", i); - unsigned long random_size = rand::uint64in(min_size, max_size); + unsigned long random_size = rand::next_u64(min_size, max_size); std::string filename = "randomfile" + std::string(index); filenames.push_back(filename); filesize.push_back(random_size); From 7f166079dbc91c43d8d3881e86e841bec27b4634 Mon Sep 17 00:00:00 2001 From: neverchanje Date: Fri, 21 Sep 2018 11:01:12 +0800 Subject: [PATCH 11/11] code refactoring --- include/dsn/tool-api/group_address.h | 8 ++++---- src/core/core/fail_point.cpp | 2 +- src/core/core/partition_resolver_simple.cpp | 2 +- src/core/core/task.cpp | 2 +- src/core/tests/rand_test.cpp | 4 ++-- src/core/tests/utils.cpp | 2 +- src/core/tools/common/fault_injector.cpp | 14 +++++++------- src/core/tools/common/network.sim.cpp | 2 +- src/core/tools/simulator/scheduler.cpp | 4 ++-- src/core/tools/simulator/task_engine.sim.cpp | 4 ++-- .../failure_detector_multimaster.cpp | 2 +- src/dist/replication/lib/replica_stub.cpp | 6 +++--- src/dist/replication/test/meta_test/misc/misc.cpp | 4 ++-- src/tests/dsn/fds_service_test.cpp | 6 +++--- 14 files changed, 31 insertions(+), 31 deletions(-) diff --git a/include/dsn/tool-api/group_address.h b/include/dsn/tool-api/group_address.h index e7ee1e80ce..6a7f8be820 100644 --- a/include/dsn/tool-api/group_address.h +++ b/include/dsn/tool-api/group_address.h @@ -61,7 +61,7 @@ class rpc_group_address : public dsn::ref_counter { alr_t l(_lock); return _members.empty() ? rpc_address::s_invalid_address - : _members[rand::uint32in(0, (uint32_t)_members.size() - 1)]; + : _members[rand::next_u32(0, (uint32_t)_members.size() - 1)]; } rpc_address next(rpc_address current) const; rpc_address leader() const @@ -159,7 +159,7 @@ inline rpc_address rpc_group_address::possible_leader() if (_members.empty()) return rpc_address::s_invalid_address; if (_leader_index == -1) - _leader_index = rand::uint32in(0, (uint32_t)_members.size() - 1); + _leader_index = rand::next_u32(0, (uint32_t)_members.size() - 1); return _members[_leader_index]; } @@ -195,11 +195,11 @@ inline rpc_address rpc_group_address::next(rpc_address current) const if (_members.empty()) return rpc_address::s_invalid_address; if (current.is_invalid()) - return _members[rand::uint32in(0, (uint32_t)_members.size() - 1)]; + return _members[rand::next_u32(0, (uint32_t)_members.size() - 1)]; else { auto it = std::find(_members.begin(), _members.end(), current); if (it == _members.end()) - return _members[rand::uint32in(0, (uint32_t)_members.size() - 1)]; + return _members[rand::next_u32(0, (uint32_t)_members.size() - 1)]; else { it++; return it == _members.end() ? _members[0] : *it; diff --git a/src/core/core/fail_point.cpp b/src/core/core/fail_point.cpp index fb30463a44..b7698b63df 100644 --- a/src/core/core/fail_point.cpp +++ b/src/core/core/fail_point.cpp @@ -98,7 +98,7 @@ bool fail_point::parse_from_string(string_view action) const std::string *fail_point::eval() { - uint32_t r = rand::uint32in(0, 100); + uint32_t r = rand::next_u32(0, 100); if (r > _freq) { return nullptr; } diff --git a/src/core/core/partition_resolver_simple.cpp b/src/core/core/partition_resolver_simple.cpp index 86982312f1..6ed36d5cb4 100644 --- a/src/core/core/partition_resolver_simple.cpp +++ b/src/core/core/partition_resolver_simple.cpp @@ -420,7 +420,7 @@ rpc_address partition_resolver_simple::get_address(const partition_configuration if (config.last_drops.size() == 0) { return rpc_address(); } else { - return config.last_drops[rand::uint32in(0, config.last_drops.size() - 1)]; + return config.last_drops[rand::next_u32(0, config.last_drops.size() - 1)]; } } diff --git a/src/core/core/task.cpp b/src/core/core/task.cpp index 86bf7934fd..c5357b0855 100644 --- a/src/core/core/task.cpp +++ b/src/core/core/task.cpp @@ -432,7 +432,7 @@ void timer_task::enqueue() { // enable timer randomization to avoid lots of timers execution simultaneously if (delay_milliseconds() == 0 && spec().randomize_timer_delay_if_zero) { - set_delay(rand::uint32in(0, _interval_milliseconds)); + set_delay(rand::next_u32(0, _interval_milliseconds)); } return task::enqueue(); diff --git a/src/core/tests/rand_test.cpp b/src/core/tests/rand_test.cpp index 88804d8a33..4d9efb4c6c 100644 --- a/src/core/tests/rand_test.cpp +++ b/src/core/tests/rand_test.cpp @@ -14,10 +14,10 @@ TEST(random, sanity) ASSERT_EQ(rand::next_u64(0), 0); ASSERT_EQ(rand::next_u64(0, 0), 0); ASSERT_EQ(rand::next_u32(0), 0); - ASSERT_EQ(rand::uint32in(0, 0), 0); + ASSERT_EQ(rand::next_u32(0, 0), 0); ASSERT_EQ(rand::next_u64(12, 12), 12); - ASSERT_EQ(rand::uint32in(12, 12), 12); + ASSERT_EQ(rand::next_u32(12, 12), 12); } constexpr int kTestSize = 1000; diff --git a/src/core/tests/utils.cpp b/src/core/tests/utils.cpp index 38e56abac0..048da5756a 100644 --- a/src/core/tests/utils.cpp +++ b/src/core/tests/utils.cpp @@ -60,7 +60,7 @@ TEST(core, crc) { char buffer[24]; for (int i = 0; i < sizeof(buffer) / sizeof(char); i++) { - buffer[i] = rand::uint32in(0, 200); + buffer[i] = rand::next_u32(0, 200); } auto c1 = dsn::utils::crc32_calc(buffer, 12, 0); diff --git a/src/core/tools/common/fault_injector.cpp b/src/core/tools/common/fault_injector.cpp index 21956b07e1..8f7f6cc73b 100644 --- a/src/core/tools/common/fault_injector.cpp +++ b/src/core/tools/common/fault_injector.cpp @@ -141,7 +141,7 @@ static void fault_on_task_begin(task *this_) { fj_opt &opt = s_fj_opts[this_->spec().code]; if (opt.execution_extra_delay_us_max > 0) { - auto d = rand::uint32in(0, opt.execution_extra_delay_us_max); + auto d = rand::next_u32(0, opt.execution_extra_delay_us_max); ddebug( "fault inject %s at %s with delay %u us", this_->spec().name.c_str(), __FUNCTION__, d); std::this_thread::sleep_for(std::chrono::microseconds(d)); @@ -187,7 +187,7 @@ static void fault_on_aio_enqueue(aio_task *this_) { fj_opt &opt = s_fj_opts[this_->spec().code]; if (this_->delay_milliseconds() == 0 && task_ext_for_fj::get(this_) == 0) { - this_->set_delay(rand::uint32in(opt.disk_io_delay_ms_min, opt.disk_io_delay_ms_max)); + this_->set_delay(rand::next_u32(opt.disk_io_delay_ms_min, opt.disk_io_delay_ms_max)); ddebug("fault inject %s at %s with delay %u ms", this_->spec().name.c_str(), __FUNCTION__, @@ -210,13 +210,13 @@ static void replace_value(std::vector &buffer_list, unsigned int offset) static void corrupt_data(message_ex *request, const std::string &corrupt_type) { if (corrupt_type == "header") - replace_value(request->buffers, rand::uint32in(0, sizeof(message_header) - 1)); + replace_value(request->buffers, rand::next_u32(0, sizeof(message_header) - 1)); else if (corrupt_type == "body") replace_value(request->buffers, - rand::uint32in(0, request->body_size() - 1) + sizeof(message_header)); + rand::next_u32(0, request->body_size() - 1) + sizeof(message_header)); else if (corrupt_type == "random") replace_value(request->buffers, - rand::uint32in(0, request->body_size() + sizeof(message_header) - 1)); + rand::next_u32(0, request->body_size() + sizeof(message_header) - 1)); else { derror("try to inject an unknown data corrupt type: %s", corrupt_type.c_str()); } @@ -250,7 +250,7 @@ static void fault_on_rpc_request_enqueue(rpc_request_task *callee) if (callee->delay_milliseconds() == 0 && task_ext_for_fj::get(callee) == 0) { if (rand::next_double01() < opt.rpc_request_delay_ratio) { callee->set_delay( - rand::uint32in(opt.rpc_message_delay_ms_min, opt.rpc_message_delay_ms_max)); + rand::next_u32(opt.rpc_message_delay_ms_min, opt.rpc_message_delay_ms_max)); ddebug("fault inject %s at %s with delay %u ms", callee->spec().name.c_str(), __FUNCTION__, @@ -288,7 +288,7 @@ static void fault_on_rpc_response_enqueue(rpc_response_task *resp) if (resp->delay_milliseconds() == 0 && task_ext_for_fj::get(resp) == 0) { if (rand::next_double01() < opt.rpc_response_delay_ratio) { resp->set_delay( - rand::uint32in(opt.rpc_message_delay_ms_min, opt.rpc_message_delay_ms_max)); + rand::next_u32(opt.rpc_message_delay_ms_min, opt.rpc_message_delay_ms_max)); ddebug("fault inject %s at %s with delay %u ms", resp->spec().name.c_str(), __FUNCTION__, diff --git a/src/core/tools/common/network.sim.cpp b/src/core/tools/common/network.sim.cpp index 08c3558050..1771003bc3 100644 --- a/src/core/tools/common/network.sim.cpp +++ b/src/core/tools/common/network.sim.cpp @@ -192,7 +192,7 @@ error_code sim_network_provider::start(rpc_channel channel, int port, bool clien uint32_t sim_network_provider::net_delay_milliseconds() const { return static_cast( - rand::uint32in(_min_message_delay_microseconds, _max_message_delay_microseconds)) / + rand::next_u32(_min_message_delay_microseconds, _max_message_delay_microseconds)) / 1000; } } diff --git a/src/core/tools/simulator/scheduler.cpp b/src/core/tools/simulator/scheduler.cpp index 4054fde297..2142955603 100644 --- a/src/core/tools/simulator/scheduler.cpp +++ b/src/core/tools/simulator/scheduler.cpp @@ -249,7 +249,7 @@ void scheduler::schedule() } if (ready_workers.size() > 0) { - int i = rand::uint32in(0, (uint32_t)ready_workers.size() - 1); + int i = rand::next_u32(0, (uint32_t)ready_workers.size() - 1); _running_thread = _threads[ready_workers[i]]; _running_thread->runnable.release(); @@ -268,7 +268,7 @@ void scheduler::schedule() // randomize the events, and see std::random_shuffle( - events->begin(), events->end(), [](int n) { return rand::uint32in(0, n - 1); }); + events->begin(), events->end(), [](int n) { return rand::next_u32(0, n - 1); }); for (auto e : *events) { if (e.app_task != nullptr) { diff --git a/src/core/tools/simulator/task_engine.sim.cpp b/src/core/tools/simulator/task_engine.sim.cpp index ed2254ec23..8c508479a8 100644 --- a/src/core/tools/simulator/task_engine.sim.cpp +++ b/src/core/tools/simulator/task_engine.sim.cpp @@ -52,13 +52,13 @@ void sim_task_queue::enqueue(task *t) dassert(0 == t->delay_milliseconds(), "delay time must be zero"); if (_tasks.size() > 0) { do { - int random_pos = rand::uint32in(0, 1000000); + int random_pos = rand::next_u32(0, 1000000); auto pr = _tasks.insert(std::map::value_type(random_pos, t)); if (pr.second) break; } while (true); } else { - int random_pos = rand::uint32in(0, 1000000); + int random_pos = rand::next_u32(0, 1000000); _tasks.insert(std::map::value_type(random_pos, t)); } diff --git a/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp b/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp index 8d75ffd5f2..5617711026 100644 --- a/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp +++ b/src/dist/failure_detector_multimaster/failure_detector_multimaster.cpp @@ -53,7 +53,7 @@ slave_failure_detector_with_multimaster::slave_failure_detector_with_multimaster } _meta_servers.group_address()->set_leader( - meta_servers[rand::uint32in(0, (uint32_t)meta_servers.size() - 1)]); + meta_servers[rand::next_u32(0, (uint32_t)meta_servers.size() - 1)]); // ATTENTION: here we disable dsn_group_set_update_leader_automatically to avoid // failure detecting logic is affected by rpc failure or rpc forwarding. diff --git a/src/dist/replication/lib/replica_stub.cpp b/src/dist/replication/lib/replica_stub.cpp index fe56e42620..0cac33cc93 100644 --- a/src/dist/replication/lib/replica_stub.cpp +++ b/src/dist/replication/lib/replica_stub.cpp @@ -537,7 +537,7 @@ void replica_stub::initialize(const replication_options &opts, bool clear /* = f [this] { on_gc(); }, std::chrono::milliseconds(_options.gc_interval_ms), 0, - std::chrono::milliseconds(rand::uint32in(0, _options.gc_interval_ms))); + std::chrono::milliseconds(rand::next_u32(0, _options.gc_interval_ms))); } // disk stat @@ -1468,7 +1468,7 @@ void replica_stub::on_gc() kv.second.rep->tracker(), std::bind(&replica_stub::trigger_checkpoint, this, kv.second.rep, true), kv.first.thread_hash(), - std::chrono::milliseconds(rand::uint32in(0, _options.gc_interval_ms / 2))); + std::chrono::milliseconds(rand::next_u32(0, _options.gc_interval_ms / 2))); } } else if (reserved_log_count > _options.log_shared_file_count_limit) { std::ostringstream oss; @@ -1494,7 +1494,7 @@ void replica_stub::on_gc() find->second.rep->tracker(), std::bind(&replica_stub::trigger_checkpoint, this, find->second.rep, true), id.thread_hash(), - std::chrono::milliseconds(rand::uint32in(0, _options.gc_interval_ms / 2))); + std::chrono::milliseconds(rand::next_u32(0, _options.gc_interval_ms / 2))); } } } diff --git a/src/dist/replication/test/meta_test/misc/misc.cpp b/src/dist/replication/test/meta_test/misc/misc.cpp index 6141cbbe63..3c2773d9ce 100644 --- a/src/dist/replication/test/meta_test/misc/misc.cpp +++ b/src/dist/replication/test/meta_test/misc/misc.cpp @@ -105,12 +105,12 @@ void generate_app_serving_replica_info(/*out*/ std::shared_ptrpartitions[i]; replica_info ri; - snprintf(buffer, 256, "disk%u", dsn::rand::uint32in(1, total_disks)); + snprintf(buffer, 256, "disk%u", dsn::rand::next_u32(1, total_disks)); ri.disk_tag = buffer; cc.collect_serving_replica(pc.primary, ri); for (const dsn::rpc_address &addr : pc.secondaries) { - snprintf(buffer, 256, "disk%u", dsn::rand::uint32in(1, total_disks)); + snprintf(buffer, 256, "disk%u", dsn::rand::next_u32(1, total_disks)); ri.disk_tag = buffer; cc.collect_serving_replica(addr, ri); } diff --git a/src/tests/dsn/fds_service_test.cpp b/src/tests/dsn/fds_service_test.cpp index 6a6fe7fe38..bebd607365 100644 --- a/src/tests/dsn/fds_service_test.cpp +++ b/src/tests/dsn/fds_service_test.cpp @@ -83,7 +83,7 @@ void FDSClientTest::SetUp() // generate a test file { - int lines = rand::uint32in(1000, 2000); + int lines = rand::next_u32(1000, 2000); FILE *fp = fopen(f1.filename.c_str(), "wb"); for (int i = 0; i < lines; ++i) { fprintf(fp, "%04d_this_is_a_simple_test_file\n", i); @@ -99,7 +99,7 @@ void FDSClientTest::SetUp() // generate another test file { - int lines = rand::uint32in(10, 20); + int lines = rand::next_u32(10, 20); FILE *fp = fopen(f2.filename.c_str(), "wb"); for (int i = 0; i < lines; ++i) { fprintf(fp, "%04d_this_is_a_simple_test_file\n", i); @@ -720,7 +720,7 @@ generate_file(const char *filename, unsigned long long file_size, char *block, u i += batch_size; for (int j = 0; j < batch_size; ++j) { - block[j] = (char)rand::uint32in(0, 255); + block[j] = (char)rand::next_u32(0, 255); } write(fd, block, batch_size); }