diff --git a/apps/EchoServer.cpp b/apps/EchoServer.cpp index f179dc609a6263f8e77ddb26c4e91dec8e0b63e5..7b92494aef8287c659779e1774b268e0f479e290 100644 --- a/apps/EchoServer.cpp +++ b/apps/EchoServer.cpp @@ -9,12 +9,14 @@ #include <cstdlib> #include <cstring> #include <iostream> +#include <random> #include <string> #include "Common.hpp" #include "Debug.hpp" #include "Runtime.hpp" -#include "Worker.hpp" +#include "RuntimeBuilder.hpp" +#include "emper-common.h" #include "emper-config.h" #include "io.hpp" @@ -28,16 +30,35 @@ static const int BACKLOG = 1024; static unsigned int computations_us = 0; static unsigned int max_computations_us = 0; +static float max_computations_probability = -1; static std::atomic<bool> quit = false; +static thread_local std::mt19937 randGenerator; +static auto getComputation() -> unsigned { + // fixed computation is computations_us + if (!max_computations_us) return computations_us; + + // computation is in range [computations_us, max_computations_us] + if (max_computations_probability == -1) { + std::uniform_int_distribution<unsigned int> distribution(computations_us, max_computations_us); + return computations_us += distribution(randGenerator); + } + + // computation is either computations_us or max_computations_us with probability + // max_computations_probability + std::uniform_real_distribution<float> distribution(0, 1); + float p = distribution(randGenerator); + return p >= max_computations_probability ? max_computations_us : computations_us; +} + auto main(int argc, char* argv[]) -> int { std::string host = HOST; std::string port = PORT; - if (argc > 4) { - std::cerr << "Usage: " << argv[0] << " [port] [computations_us] [max_computations_us]" - << std::endl; + if (argc > 5) { + std::cerr << "Usage: " << argv[0] << " [port] [computations_us]" + << " [max_computations_us] [max_computations_probability]" << std::endl; exit(EXIT_FAILURE); } @@ -55,6 +76,12 @@ auto main(int argc, char* argv[]) -> int { DIE_MSG("max_computations_us must be bigger than computations_us"); } + if (argc > 4) { + max_computations_probability = std::stof(argv[4]); + if (max_computations_probability < 0 || max_computations_probability > 1) + DIE_MSG("max_computations_probability must be in [0,1]"); + } + std::cout << "Echoserver listening on " << host << ":" << port; if (computations_us) { std::cout << " with " << computations_us; @@ -63,7 +90,13 @@ auto main(int argc, char* argv[]) -> int { } std::cout << std::endl; - Runtime runtime; + RuntimeBuilder runtimeBuilder; + if (max_computations_us) { + runtimeBuilder.newWorkerHook([](workerid_t id) { randGenerator.seed(id); }); + } + + auto runtime = runtimeBuilder.build(); + auto serverFunc = [](int socket) { // NOLINTNEXTLINE(modernize-avoid-c-arrays) char buf[1024]; @@ -84,12 +117,7 @@ auto main(int argc, char* argv[]) -> int { } if (computations_us) { - unsigned int computation = computations_us; - if (max_computations_us) { - // Worker::rand is always positiv. Why does it return int? - computation += Worker::rand() % (max_computations_us - computations_us); - } - + unsigned int computation = getComputation(); const auto start = std::chrono::steady_clock::now(); const auto deadline = start + std::chrono::microseconds(computation); // TODO: The suppressed linter error below may be a false positive