Skip to content
Snippets Groups Projects

Improved echo client

Merged Florian Fischer requested to merge aj46ezos/emper:improved_echo_client into master
1 file
+ 46
14
Compare changes
  • Side-by-side
  • Inline
+ 46
14
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2021 Florian Fischer
#include <fcntl.h>
#include <netdb.h> //for getaddrinfo
#include <netdb.h> //for getaddrinfo
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h> // for shutdown, socket, AF_INET
#include <sys/stat.h>
#include <unistd.h>
#include <algorithm> // for find
#include <array>
#include <atomic>
#include <cerrno> // for errno, ECANCELED
#include <chrono> // for nanoseconds, duration, durat...
@@ -31,6 +34,9 @@ using emper::io::CloseFuture;
using emper::io::RecvFuture;
using emper::io::SendFuture;
using std::chrono::duration_cast;
using std::chrono::nanoseconds;
// Defaults
const int DECIMAL = 10;
const std::string HOST = "0.0.0.0";
@@ -70,8 +76,12 @@ static void clientFunc(uint64_t client_id, Semaphore& readySem, Semaphore& start
spawn([&, next_client_id] { clientFunc(next_client_id, readySem, startSem, cps); }, cps);
}
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
char* buf[2];
int enable = 1;
if (setsockopt(client_sock, IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(enable)) == -1) {
DIE_MSG_ERRNO("setsockopt failed");
}
std::array<char*, 2> buf;
buf[0] = new char[size];
buf[1] = new char[size];
uint64_t avg_ns = 0;
@@ -116,7 +126,7 @@ static void clientFunc(uint64_t client_id, Semaphore& readySem, Semaphore& start
DIE_MSG("got unexpected echo from server");
}
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
auto duration = duration_cast<nanoseconds>(end - start);
uint64_t ns = duration.count();
if (unlikely(avg_ns == 0)) {
avg_ns = ns;
@@ -202,15 +212,7 @@ auto main(int argc, char* argv[]) -> int {
}
int out_fd = STDOUT_FILENO;
char* output_file = getOption(argc, argv, "-f");
if (output_file) {
out_fd = open(output_file, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
if (out_fd < 0) {
DIE_MSG_ERRNO("opening output file failed");
}
}
int err = getaddrinfo(host.c_str(), port.c_str(), nullptr, &server);
if (err) {
@@ -230,6 +232,8 @@ auto main(int argc, char* argv[]) -> int {
Semaphore readySemaphore;
Semaphore startSemaphore;
auto connect_start = std::chrono::high_resolution_clock::now();
// start first client batch
for (size_t i = 0; i < server_backlog; ++i) {
size_t next_client_id = client_ids.fetch_add(1);
@@ -246,6 +250,8 @@ auto main(int argc, char* argv[]) -> int {
readySemaphore.acquire();
}
auto echo_start = std::chrono::high_resolution_clock::now();
// start the clients
for (size_t i = 0; i < clients; ++i) {
startSemaphore.release();
@@ -254,15 +260,41 @@ auto main(int argc, char* argv[]) -> int {
// await the clients
cps.wait();
auto echo_end = std::chrono::high_resolution_clock::now();
uint64_t avg_ns = client_avgs[0];
for (size_t i = 1; i < clients; ++i) {
avg_ns += client_avgs[i];
avg_ns /= 2;
}
auto connect_duration = duration_cast<nanoseconds>(echo_start - connect_start).count();
auto echo_duration = duration_cast<nanoseconds>(echo_end - echo_start).count();
auto total_duration = duration_cast<nanoseconds>(echo_end - connect_start).count();
std::stringstream sst;
sst << "clients,iterations,size,time" << std::endl;
sst << clients << "," << iterations << "," << size << "," << avg_ns << std::endl;
bool exists = true;
if (output_file) {
exists = access(output_file, W_OK) == 0;
int openflags;
int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
if (!exists) {
openflags = O_CREAT | O_WRONLY;
} else {
openflags = O_APPEND;
}
out_fd = emper::io::openAndWait(output_file, openflags, mode);
if (out_fd < 0) {
DIE_MSG_ERRNO("opening output file failed");
}
}
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;
auto output = sst.str();
if (emper::io::writeFileAndWait(out_fd, output.c_str(), output.size()) < 0) {
Loading