From: Peter Iannucci Date: Thu, 19 Dec 2013 01:53:36 +0000 (-0800) Subject: All random numbers generated via one PRNG seeded in one place. X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/commitdiff_plain/c06ef44e7af1571710fd31dd0ab068dd77b1eb2d All random numbers generated via one PRNG seeded in one place. --- diff --git a/Makefile.osx b/Makefile.osx index ef15988..d352c69 100644 --- a/Makefile.osx +++ b/Makefile.osx @@ -10,8 +10,7 @@ ifeq "$(USE_CLANG)" "1" PEDANTRY += \ -Weverything -pedantic-errors -Werror -Wno-c++98-compat-pedantic \ - -Wno-padded -Wno-global-constructors -Wno-exit-time-destructors \ - -pedantic -Wall -Wextra -Weffc++ + -Wno-padded -pedantic -Wall -Wextra -Weffc++ STDLIB += -stdlib=libc++ CXX = clang++-mp-3.4 diff --git a/lock_client.cc b/lock_client.cc index 009e051..e1bd62f 100644 --- a/lock_client.cc +++ b/lock_client.cc @@ -20,8 +20,6 @@ void lock_state::signal(thread::id who) { c[who].notify_one(); } -in_port_t lock_client::last_port = 0; - lock_state & lock_client::get_lock_state(lock_protocol::lockid_t lid) { lock sl(lock_table_lock); return lock_table[lid]; // creates the lock if it doesn't already exist @@ -32,10 +30,8 @@ lock_client::lock_client(string xdst, lock_release_user *_lu) : lu(_lu), next_xi if (cl->bind() < 0) LOG << "lock_client: call bind"; - srandom((uint32_t)time(NULL)^last_port); - rlock_port = ((random()%32000) | (0x1 << 10)); + rlock_port = std::uniform_int_distribution(1024,32000+1024)(global->random_generator); id = "127.0.0.1:" + std::to_string(rlock_port); - last_port = rlock_port; rlsrpc = unique_ptr(new rpcs(rlock_port)); rlsrpc->reg(rlock_protocol::revoke, &lock_client::revoke_handler, this); rlsrpc->reg(rlock_protocol::retry, &lock_client::retry_handler, this); diff --git a/lock_client.h b/lock_client.h index 74f17a8..7a4d43f 100644 --- a/lock_client.h +++ b/lock_client.h @@ -58,7 +58,6 @@ class lock_client { lock_map lock_table; lock_state & get_lock_state(lock_protocol::lockid_t lid); public: - static in_port_t last_port; lock_client(string xdst, lock_release_user *l = 0); ~lock_client(); lock_protocol::status acquire(lock_protocol::lockid_t); diff --git a/lock_smain.cc b/lock_smain.cc index c6f3356..ae3b51d 100644 --- a/lock_smain.cc +++ b/lock_smain.cc @@ -9,8 +9,6 @@ int main(int argc, char *argv[]) { setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); - srandom((uint32_t)getpid()); - if(argc != 3){ LOG_NONMEMBER << "Usage: " << argv[0] << " [master:]port [me:]port"; exit(1); diff --git a/lock_tester.cc b/lock_tester.cc index a546e09..07961c7 100644 --- a/lock_tester.cc +++ b/lock_tester.cc @@ -8,20 +8,18 @@ // must be >= 2 const int nt = 6; //XXX: lab1's rpc handlers are blocking. Since rpcs uses a thread pool of 10 threads, we cannot test more than 10 blocking rpc. -static string dst; static lock_client *lc[nt]; -static lock_protocol::lockid_t a = "1"; -static lock_protocol::lockid_t b = "2"; -static lock_protocol::lockid_t c = "3"; +static const char * a = "1"; +static const char * b = "2"; // check_grant() and check_release() check that the lock server // doesn't grant the same lock to both clients. // it assumes that lock names are distinct in the first byte. static int ct[256]; -static std::mutex count_mutex; +static std::mutex * count_mutex; static void check_grant(lock_protocol::lockid_t lid) { - lock ml(count_mutex); + lock ml(*count_mutex); int x = lid[0] & 0x0f; if (ct[x] != 0) { LOG_NONMEMBER << "error: server granted " << lid << " twice"; @@ -31,7 +29,7 @@ static void check_grant(lock_protocol::lockid_t lid) { } static void check_release(lock_protocol::lockid_t lid) { - lock ml(count_mutex); + lock ml(*count_mutex); int x = lid[0] & 0x0f; if (ct[x] != 1) { LOG_NONMEMBER << "error: client released un-held lock " << lid; @@ -113,19 +111,20 @@ int main(int argc, char *argv[]) { global = new t4_state('c'); + count_mutex = new std::mutex(); + thread th[nt]; int test = 0; setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); - srandom((uint32_t)getpid()); if (argc < 2) { LOG_NONMEMBER << "Usage: " << argv[0] << " [host:]port [test]"; exit(1); } - dst = argv[1]; + string dst = argv[1]; if (argc > 2) { test = atoi(argv[2]); diff --git a/rpc/connection.cc b/rpc/connection.cc index 31ec5fa..8966cc2 100644 --- a/rpc/connection.cc +++ b/rpc/connection.cc @@ -56,7 +56,7 @@ bool connection::send(const string & b) { wpdu_ = {inflight, b, 0}; - if (lossy_ && (random()%100) < lossy_) { + if (std::bernoulli_distribution(lossy_*.01)(global->random_generator)) { IF_LEVEL(1) LOG << "send LOSSY TEST shutdown fd " << fd; shutdown(fd,SHUT_RDWR); } diff --git a/rpc/rpc.cc b/rpc/rpc.cc index 2889db9..5d28f8f 100644 --- a/rpc/rpc.cc +++ b/rpc/rpc.cc @@ -63,17 +63,11 @@ using std::list; using namespace std::chrono; -inline void set_rand_seed() { - auto now = time_point_cast(steady_clock::now()); - srandom((uint32_t)now.time_since_epoch().count()^(uint32_t)getpid()); -} - static sockaddr_in make_sockaddr(const string & hostandport); rpcc::rpcc(const string & d) : dst_(make_sockaddr(d)) { - set_rand_seed(); - clt_nonce_ = (nonce_t)random(); + clt_nonce_ = (nonce_t)global->random_generator(); char *loss_env = getenv("RPC_LOSSY"); if (loss_env) @@ -335,8 +329,7 @@ compress: rpcs::rpcs(in_port_t p1) : port_(p1) { - set_rand_seed(); - nonce_ = (nonce_t)random(); + nonce_ = (nonce_t)global->random_generator(); IF_LEVEL(2) LOG << "created with nonce " << nonce_; reg(rpc_protocol::bind, &rpcs::rpcbind, this); diff --git a/rpc/rpctest.cc b/rpc/rpctest.cc index f8395e9..051e564 100644 --- a/rpc/rpctest.cc +++ b/rpc/rpctest.cc @@ -13,7 +13,7 @@ static rpcs *server; // server rpc object static rpcc *clients[NUM_CL]; // client rpc object -static string dst; //server's ip address +static string * dst; //server's ip address static in_port_t port; using std::cout; @@ -59,7 +59,7 @@ int srv::handle_fast(int & r, const int a) { } int srv::handle_slow(int & r, const int a) { - usleep(random() % 500); + usleep(std::uniform_int_distribution(0,500)(global->random_generator)); r = a + 2; return 0; } @@ -122,7 +122,7 @@ static void client1(size_t cl) { size_t which_cl = cl % NUM_CL; for(int i = 0; i < 100; i++){ - unsigned long arg = (random() % 2000); + auto arg = std::uniform_int_distribution(0,2000)(global->random_generator); string rep; int ret = clients[which_cl]->call(srv_protocol::bigrep, rep, arg); VERIFY(ret == 0); @@ -134,8 +134,8 @@ static void client1(size_t cl) { // test rpc replies coming back not in the order of // the original calls -- i.e. does xid reply dispatch work. for(int i = 0; i < 100; i++){ - int which = (random() % 2); - int arg = (random() % 1000); + bool which = std::bernoulli_distribution()(global->random_generator); + int arg = std::uniform_int_distribution<>(0,1000)(global->random_generator); int rep = -1; auto start = steady_clock::now(); @@ -157,7 +157,7 @@ static void client2(size_t cl) { time(&t1); while(time(0) - t1 < 10){ - unsigned long arg = (random() % 2000); + auto arg = std::uniform_int_distribution(0,2000)(global->random_generator); string rep; int ret = clients[which_cl]->call(srv_protocol::bigrep, rep, arg); if ((unsigned long)rep.size()!=arg) @@ -255,7 +255,7 @@ static void lossy_test() { for (int i = 0; i < NUM_CL; i++) { delete clients[i]; - clients[i] = new rpcc(dst); + clients[i] = new rpcc(*dst); VERIFY(clients[i]->bind()==0); } @@ -281,7 +281,7 @@ static void failure_test() { delete server; - client1 = new rpcc(dst); + client1 = new rpcc(*dst); VERIFY (client1->bind(milliseconds(3000)) < 0); cout << " -- create new client and try to bind to failed server .. failed ok" << endl; @@ -296,7 +296,7 @@ static void failure_test() { delete client; - clients[0] = client = new rpcc(dst); + clients[0] = client = new rpcc(*dst); VERIFY (client->bind() >= 0); VERIFY (client->bind() < 0); @@ -324,7 +324,7 @@ static void failure_test() { delete client; startserver(); - clients[0] = client = new rpcc(dst); + clients[0] = client = new rpcc(*dst); VERIFY (client->bind() >= 0); cout << " -- delete existing rpc client and server, create replacements.. ok" << endl; @@ -351,7 +351,6 @@ int main(int argc, char *argv[]) { bool isclient = false; bool isserver = false; - srandom((uint32_t)getpid()); port = 20000 + (getpid() % 10000); int ch = 0; @@ -382,7 +381,7 @@ int main(int argc, char *argv[]) { } if (debug_level > 0) { - DEBUG_LEVEL = debug_level; + global->DEBUG_LEVEL = debug_level; IF_LEVEL(1) LOG_NONMEMBER << "DEBUG LEVEL: " << debug_level; } @@ -395,7 +394,7 @@ int main(int argc, char *argv[]) { if (isclient) { // server's address. - dst = "127.0.0.1:" + std::to_string(port); + dst = new string("127.0.0.1:" + std::to_string(port)); // start the client. bind it to the server. @@ -404,7 +403,7 @@ int main(int argc, char *argv[]) { // be only one rpcc per process. you probably need one // rpcc per server. for (int i = 0; i < NUM_CL; i++) { - clients[i] = new rpcc(dst); + clients[i] = new rpcc(*dst); VERIFY (clients[i]->bind() == 0); } diff --git a/threaded_log.cc b/threaded_log.cc index 0160f33..3218e33 100644 --- a/threaded_log.cc +++ b/threaded_log.cc @@ -1,20 +1,14 @@ -#include "threaded_log.h" #include "t4.h" - -static std::mutex log_mutex; -static std::map thread_name_map; -static int next_thread_num = 0; -static std::map instance_name_map; -static int next_instance_num = 0; -int DEBUG_LEVEL = 0; +#include "types.h" +#include "threaded_log.h" using namespace std::chrono; locked_ostream && _log_prefix(locked_ostream && f, const string & file, const string & func) { auto thread = std::this_thread::get_id(); - int tid = thread_name_map[thread]; + int tid = global->thread_name_map[thread]; if (tid==0) - tid = thread_name_map[thread] = ++next_thread_num; + tid = global->thread_name_map[thread] = ++global->next_thread_num; auto utime = duration_cast( system_clock::now().time_since_epoch()).count() % 1000000000; f << std::setfill('0') << std::dec << std::left << std::setw(9) << utime << " "; @@ -24,13 +18,17 @@ locked_ostream && _log_prefix(locked_ostream && f, const string & file, const st } locked_ostream && _log_member(locked_ostream && f, const void *ptr) { - int id = instance_name_map[ptr]; + int id = global->instance_name_map[ptr]; if (id == 0) - id = instance_name_map[ptr] = ++next_instance_num; + id = global->instance_name_map[ptr] = ++global->next_instance_num; f << "#" << std::left << std::setw(2) << id << " "; return std::move(f); } +int _log_debug_level() { + return global->DEBUG_LEVEL; +} + lock _log_lock() { - return lock(log_mutex); + return lock(global->log_mutex); } diff --git a/threaded_log.h b/threaded_log.h index 7b1dd75..9a83bfb 100644 --- a/threaded_log.h +++ b/threaded_log.h @@ -1,10 +1,8 @@ #ifndef threaded_log_h #define threaded_log_h -#include "types.h" - -extern char log_thread_prefix; -extern int DEBUG_LEVEL; +#include +#include struct locked_ostream { std::ostream & s; @@ -17,11 +15,12 @@ struct locked_ostream { locked_ostream && _log_prefix(locked_ostream && f, const string & file, const string & func); locked_ostream && _log_member(locked_ostream && f, const void *ptr); +int _log_debug_level(); lock _log_lock(); #define LOG_NONMEMBER _log_prefix(locked_ostream{std::cerr, _log_lock()}, __FILE__, __func__) #define LOG _log_member(LOG_NONMEMBER, (const void *)this) -#define IF_LEVEL(level) if(DEBUG_LEVEL >= abs(level)) +#define IF_LEVEL(level) if(_log_debug_level() >= abs(level)) #endif