diff --git a/base/io_generator.cc b/base/io_generator.cc index 918a9ed..fd13b76 100644 --- a/base/io_generator.cc +++ b/base/io_generator.cc @@ -1,5 +1,7 @@ #include "base/io_generator.h" #include "base/sequence_generator.h" +#include +#include #include #include #include @@ -31,19 +33,23 @@ namespace { typedef std::shared_ptr ptr; op_generator(base::req_op op1) - : op1_(op1), op2_(op1), op1_pct_(100) { + : op1_(op1), op2_(op1), op1_pct_(100), + rand_seed_(std::chrono::high_resolution_clock::now().time_since_epoch().count()), + op_engine_(rand_seed_) { } op_generator(base::req_op op1, base::req_op op2, unsigned op1_pct) - : op1_(op1), op2_(op2), op1_pct_(op1_pct) { + : op1_(op1), op2_(op2), op1_pct_(op1_pct), + rand_seed_(std::chrono::high_resolution_clock::now().time_since_epoch().count()), + op_engine_(rand_seed_) { if (op1_pct > 100) throw std::runtime_error("invalid percentage"); } base::req_op next_op() { - if (static_cast(std::rand()) % 100 > op1_pct_) + if (op_engine_() % 100 > op1_pct_) return op2_; return op1_; } @@ -52,6 +58,9 @@ namespace { base::req_op op1_; base::req_op op2_; unsigned op1_pct_; + uint64_t rand_seed_; + + std::mt19937 op_engine_; }; //-------------------------------- diff --git a/base/sequence_generator.cc b/base/sequence_generator.cc index cd0e3f9..b6bfa2c 100644 --- a/base/sequence_generator.cc +++ b/base/sequence_generator.cc @@ -1,5 +1,7 @@ #include "base/run_set.h" #include "base/sequence_generator.h" +#include +#include #include //---------------------------------------------------------------- @@ -80,6 +82,9 @@ namespace { : begin_(begin), step_(step), max_forward_steps_(seq_nr), + rand_seed_(std::chrono::high_resolution_clock::now().time_since_epoch().count()), + results_engine_(rand_seed_), + steps_engine_(rand_seed_), nr_generated_(0) { if (!size || !step || !seq_nr) @@ -93,8 +98,14 @@ namespace { if (!max_forward_steps_ || max_forward_steps_ > nr_steps_) throw std::runtime_error("invalid number of forward steps"); - if (max_forward_steps_ > 1) + results_distr_ = std::uniform_int_distribution(0, + nr_steps_ - 1); + + if (max_forward_steps_ > 1) { + steps_distr_ = std::uniform_int_distribution(1, + max_forward_steps_); reset_forward_generator(); + } } uint64_t next() { @@ -109,7 +120,7 @@ namespace { void reset_forward_generator() { uint64_t begin = peek_random_step(); - unsigned seq_nr = (std::rand() % max_forward_steps_) + 1; + unsigned seq_nr = steps_distr_(steps_engine_); base::run_set::const_iterator it = rand_map_.upper_bound(begin); if (it != rand_map_.end()) seq_nr = std::min(seq_nr, *it->begin_ - begin); @@ -148,12 +159,13 @@ namespace { } } - uint64_t peek_random_step() const { + // TODO: improve the complexity of generating unique sequence + uint64_t peek_random_step() { uint64_t step_idx; bool found = true; while (found) { - step_idx = std::rand() % nr_steps_; + step_idx = results_distr_(results_engine_); found = rand_map_.member(step_idx); } @@ -164,7 +176,12 @@ namespace { uint64_t nr_steps_; uint64_t step_; unsigned max_forward_steps_; + uint64_t rand_seed_; + std::mt19937_64 results_engine_; + std::mt19937_64 steps_engine_; + std::uniform_int_distribution results_distr_; + std::uniform_int_distribution steps_distr_; base::run_set rand_map_; uint64_t nr_generated_; forward_sequence_generator forward_gen_; diff --git a/thin-provisioning/damage_generator.cc b/thin-provisioning/damage_generator.cc index 1518296..f45dad8 100644 --- a/thin-provisioning/damage_generator.cc +++ b/thin-provisioning/damage_generator.cc @@ -1,3 +1,5 @@ +#include +#include #include "damage_generator.h" using namespace thin_provisioning; @@ -13,12 +15,14 @@ namespace { base::run_set visited; block_address nr_visited = 0; - srand(time(NULL)); + uint64_t rand_seed(std::chrono::high_resolution_clock::now().time_since_epoch().count()); + std::mt19937 rand_engine(rand_seed); + while (nr_blocks) { if (nr_visited == sm_size) break; - block_address b = rand() % sm_size; + block_address b = rand_engine() % sm_size; if (visited.member(b)) continue;