diff --git a/apps/EchoClient.cpp b/apps/EchoClient.cpp index 28fe707daff38a693f5d0b759bc4fdc70b7c71b7..3712671ca09148b3c1e51770ac3c09a542cfd519 100644 --- a/apps/EchoClient.cpp +++ b/apps/EchoClient.cpp @@ -50,12 +50,22 @@ const size_t SERVER_BACKLOG = 1024; std::string host = HOST; std::string port = PORT; size_t iterations = ITERATIONS; +size_t execution_seconds = 0; size_t clients = CLIENTS; size_t size = SIZE; size_t server_backlog = SERVER_BACKLOG; +std::atomic<bool> terminate = false; + std::atomic<size_t> client_ids = 0; -uint64_t* client_avgs; + +struct ClientResult { + size_t iterations; + size_t avg_ns; +}; +using ClientResult = struct ClientResult; + +struct ClientResult* clientResults; struct addrinfo* server; @@ -89,7 +99,8 @@ static void clientFunc(uint64_t client_id, Semaphore& readySem, Semaphore& start readySem.release(); startSem.acquire(); - for (size_t i = 0; i < iterations; ++i) { + size_t i = 0; + while (i < iterations && !terminate.load(std::memory_order_relaxed)) { char* outBuf = buf[i % 2]; char* inBuf = buf[(i + 1) % 2]; @@ -134,6 +145,8 @@ static void clientFunc(uint64_t client_id, Semaphore& readySem, Semaphore& start avg_ns += ns; avg_ns /= 2; } + + i++; } // Shutdown and close the client socket; @@ -149,7 +162,8 @@ static void clientFunc(uint64_t client_id, Semaphore& readySem, Semaphore& start cf.wait(); - client_avgs[client_id] = avg_ns; + clientResults[client_id].avg_ns = avg_ns; + clientResults[client_id].iterations = i; } auto getOption(int argc, char** argv, const std::string& option) -> char* { @@ -170,8 +184,8 @@ static auto existsOption(int argc, char** argv, const std::string& option) -> bo static void printUsage(char* name) { std::cerr << "Usage: " << name - << "[-h] [-p <port>] [-c <clients>] [-i <iterations>] [-a <address>] [-s <size>] [-b " - "<server backlog>] [-f <output-file>]" + << "[-h] [-p <port>] [-c <clients>] [-a <address>] [-s <size>] [-b <server backlog>]" + " [-f <output-file>] [-i <iterations> | -t <execution time in sec>]" << std::endl; } @@ -201,6 +215,16 @@ auto main(int argc, char* argv[]) -> int { iterations = strtol(iterations_s, nullptr, DECIMAL); } + char* time_s = getOption(argc, argv, "-t"); + if (time_s) { + if (iterations_s) { + std::cerr << "-t and -i are mutual exclusive" << std::endl; + printUsage(argv[0]); + exit(EXIT_FAILURE); + } + execution_seconds = strtol(time_s, nullptr, DECIMAL); + } + char* size_s = getOption(argc, argv, "-s"); if (size_s) { size = strtol(size_s, nullptr, DECIMAL); @@ -227,7 +251,7 @@ auto main(int argc, char* argv[]) -> int { Runtime runtime; Fiber* alphaFiber = Fiber::from([&] { - client_avgs = new uint64_t[clients]; + clientResults = new ClientResult[clients]; CPS cps; Semaphore readySemaphore; Semaphore startSemaphore; @@ -250,6 +274,14 @@ auto main(int argc, char* argv[]) -> int { readySemaphore.acquire(); } + if (execution_seconds) { + iterations = SIZE_MAX; + async([] { + sleep(execution_seconds); + terminate.store(true, std::memory_order_relaxed); + }); + } + auto echo_start = std::chrono::high_resolution_clock::now(); // start the clients @@ -262,10 +294,14 @@ auto main(int argc, char* argv[]) -> int { auto echo_end = std::chrono::high_resolution_clock::now(); - uint64_t avg_ns = client_avgs[0]; + uint64_t avg_ns = clientResults[0].avg_ns; + uint64_t avg_iterations = clientResults[0].iterations; for (size_t i = 1; i < clients; ++i) { - avg_ns += client_avgs[i]; + avg_ns += clientResults[i].avg_ns; avg_ns /= 2; + + avg_iterations += clientResults[i].iterations; + avg_iterations /= 2; } auto connect_duration = duration_cast<nanoseconds>(echo_start - connect_start).count(); @@ -293,8 +329,8 @@ auto main(int argc, char* argv[]) -> int { if (!exists) { sst << "clients,iterations,size,avg_ns,connect,echo,total" << std::endl; } - sst << clients << "," << iterations << "," << size << "," << avg_ns << "," << connect_duration - << "," << echo_duration << "," << total_duration << std::endl; + sst << clients << "," << avg_iterations << "," << size << "," << avg_ns << "," + << connect_duration << "," << echo_duration << "," << total_duration << std::endl; auto output = sst.str(); if (emper::io::writeFileAndWait(out_fd, output.c_str(), output.size()) < 0) { @@ -305,7 +341,7 @@ auto main(int argc, char* argv[]) -> int { emper::io::closeAndForget(out_fd); } - delete[] client_avgs; + delete[] clientResults; exit(EXIT_SUCCESS); });