Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • abp-queue
  • async_network2
  • burak
  • cactus_stack_devel
  • cactus_stack_devel_one_commit
  • cast-if-future
  • ci-bump-test
  • client-load-change
  • completer-strategies
  • cppcheck
  • emper-fix-invalid-conv
  • flow
  • fused-continuation-and-completion-stealing
  • libc++
  • libstdc++-asserts
  • linux-version-construct-on-first-use
  • master
  • msan
  • new-delete-leaks
  • remote-put-get-free-context-cycle
  • thread_safe_log_config
  • attic/clang-release-tls-optimization-debug-and-fix
  • attic/continuation-stealing-dev
23 results

Target

Select target project
  • flow/emper
  • aj46ezos/emper
  • i4/manycore/emper
3 results
Select Git revision
  • burak
  • cactus_stack_devel
  • emper-fs-eval
  • io-sleep-main
  • io_uring_network
  • kickoff-without-ret
  • master
  • tsan_ci_target
  • worker_exclusive_uring_no_partial_completion
  • worker_exclusive_uring_weak
10 results
Show changes
Commits on Source (3)
......@@ -102,6 +102,10 @@ fix-includes: all
stresstest: test
./stresstest/stresstest.sh build/tests/simplest_fib_test
PHONY: test-echo
test-echo:
./tools/test-echo-server-and-client
# TODO: Determine how we can run also jobs from the 'test' stage,
# e.g. test-gcc.
.PHONY: gitlab-runner
......
......@@ -18,7 +18,8 @@
#include <cstring> // for memcmp
#include <iomanip>
#include <iostream> // for operator<<, basic_ostream, endl
#include <string> // for allocator, string, char_traits
#include <ratio>
#include <string>
#include <thread>
#include <utility>
......@@ -69,6 +70,8 @@ size_t size = SIZE;
size_t server_backlog = SERVER_BACKLOG;
bool linked_futures;
bool histogram = false;
static ssize_t maxLowLoadClients = -1;
static std::chrono::milliseconds loadSwitchPeriod(1000);
std::atomic<bool> terminate = false;
......@@ -225,6 +228,24 @@ class Client {
}
}
[[nodiscard]] auto shouldYield() const -> bool {
if (maxLowLoadClients < 0) {
return false;
}
if (id < static_cast<size_t>(maxLowLoadClients)) {
return false;
}
auto now = std::chrono::steady_clock::now();
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
auto ms_since_epoch = now_ms.time_since_epoch();
auto ms_since_epoch_duration =
std::chrono::duration_cast<std::chrono::milliseconds>(ms_since_epoch);
uint64_t periodNum = ms_since_epoch_duration / loadSwitchPeriod;
return periodNum % 2;
}
public:
template <bool collectTimeStamps = false>
void run() {
......@@ -237,6 +258,11 @@ class Client {
startSem.acquire();
while (iteration < iterations && !terminate.load(std::memory_order_relaxed)) {
if (shouldYield()) {
emper::yield();
continue;
}
SendFuture sendFuture(sock, outBuf, size, MSG_NOSIGNAL);
RecvFuture recvFuture(sock, inBuf, size, MSG_WAITALL);
......@@ -361,8 +387,10 @@ static void printUsage(char* name) {
std::cerr
<< "Usage: " << name
<< "[-h] [-p <port>] [-c <clients>] [-a <address>] [-s <size>] [-b <server backlog>]"
" [-f <output-file>] [-i <iterations> | -t <execution time in sec>] [--linked-futures]"
<< std::endl;
<< std::endl
<< "[-f <output-file>] [-i <iterations> | -t <execution time in sec>] [--linked-futures]"
<< std::endl
<< "[--max-low-load-clients <num>] [--load-switch-period-ms <num>]" << std::endl;
}
auto main(int argc, char* argv[]) -> int {
......@@ -446,6 +474,25 @@ auto main(int argc, char* argv[]) -> int {
}
}
char* max_low_load_clients = getOption(argc, argv, "--max-low-load-clients");
if (max_low_load_clients) {
maxLowLoadClients = std::stoi(max_low_load_clients);
if (static_cast<size_t>(maxLowLoadClients) >= nclients) {
DIE_MSG("--max-low-load-clients " << maxLowLoadClients
<< " must be smaller than the total number of clients "
<< nclients);
}
}
char* load_switch_period_ms_string = getOption(argc, argv, "--load-switch-period-ms");
if (load_switch_period_ms_string) {
if (!max_low_load_clients) {
DIE_MSG("Can't use --load-switch-period-ms without --max-low-load-clients");
}
int load_switch_period_ms = std::stoi(load_switch_period_ms_string);
loadSwitchPeriod = std::chrono::milliseconds(load_switch_period_ms);
}
int err = getaddrinfo(host.c_str(), port.c_str(), nullptr, &server);
if (err) {
if (err == EAI_SYSTEM) {
......
......@@ -63,6 +63,7 @@ auto main(int argc, char* argv[]) -> int {
if (unlikely(bytes_recv == 5 && strncmp("quit\n", buf, bytes_recv) == 0)) {
quit = true;
std::cout << "Echoserver received 'quit' command from client" << std::endl;
Runtime::getRuntime()->initiateTermination();
break;
}
......
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-3.0-or-later
# Copyright © 2021 Florian Schmaus
set -euo pipefail
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
ROOTDIR="$(readlink -f "${SCRIPTDIR}/..")"
BUILDDIR="${ROOTDIR}/build"
echoerr() { echo "$@" 1>&2; }
PRESERVE_TMPDIR=false
while getopts :dp OPT; do
case $OPT in
d)
PRESERVE_TMPDIR=true
set -x
;;
p)
PRESERVE_TMPDIR=true
;;
*)
print "usage: ${0##*/} [-d] [--] ARGS..."
exit 2
esac
done
shift $(( OPTIND - 1 ))
OPTIND=1
if [[ ! -L "${BUILDDIR}" ]]; then
make -C "${ROOTDIR}"
fi
TMPDIR=$(mktemp --directory --tmpdir=/var/tmp emper-echo-test.XXXX)
cleanup() {
if ! $PRESERVE_TMPDIR; then
rm -rf "${TMPDIR}"
fi
# Ensure that we don't leave a stray echoserver
if pgrep --count echoserver > /dev/null; then
killall echoserver
fi
}
trap cleanup EXIT
echo "Starting echo client/server test. Using ${TMPDIR} for logs"
readonly ECHO_CLIENT="${BUILDDIR}/apps/echoclient"
readonly ECHO_SERVER="${BUILDDIR}/apps/echoserver"
run_echo_client_and_server() {
local -r run_name="${1}"
local -r echo_client_opts="${2-}"
local -r logdir="${TMPDIR}/${run_name}"
mkdir "${logdir}"
local -r echo_server_pidfile="${logdir}/echo_server.pid"
echo "Performing echo client/server ${run_name} run. Logdir: ${logdir}"
"${ECHO_SERVER}" \
> "${logdir}/server.log" \
2> "${logdir}/server.err" &
echo "${!}" >> "${echo_server_pidfile}"
# Wait till the echo server port becomes accessible.
# https://stackoverflow.com/a/50055449/194894
timeout 30 bash -c \
'until printf "" 2>>/dev/null >>/dev/tcp/${0}/${1}; do sleep 1; done' \
localhost 12345
set +e
# shellcheck disable=SC2086
"${ECHO_CLIENT}" \
${echo_client_opts} \
> "${logdir}/client.log" \
2> "${logdir}/client.err"
local echo_client_ret="${?}"
set -e
local echo_server_pid
echo_server_pid=$(cat "${echo_server_pidfile}")
if ps -p "${echo_server_pid}" > /dev/null; then
# TODO: Re-enable this warning once the client is sending a
# 'quit' once it is finished.
# echoerr "WARNING: echo server was not terminated by client"
kill "${echo_server_pid}"
fi
if [[ "${echo_client_ret}" -ne 0 ]]; then
echoerr "ERROR: Echo client exited with ${echo_client_ret}"
PRESERVE_TMPDIR=true
exit 1
fi
}
run_echo_client_and_server "quicktest" "-c 10 -i 10"
run_echo_client_and_server "load-switch" "-c 100 -i 1000 --max-low-load-clients 50 --load-switch-period-ms 250"