Skip to content

Commit

Permalink
Fixes an infinite loop in termbnech.cpp and add some overall improvem…
Browse files Browse the repository at this point in the history
…ents

Signed-off-by: Christian Parpart <[email protected]>
  • Loading branch information
christianparpart committed Mar 17, 2024
1 parent f7ba82f commit e2246d4
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 49 deletions.
37 changes: 19 additions & 18 deletions libtermbench/termbench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ void Benchmark::add(unique_ptr<Test> _test)
tests_.emplace_back(std::move(_test));
}

void Benchmark::writeOutput(Buffer const& testBuffer)
{
auto const output = testBuffer.output();
auto remainingBytes = totalSizeBytes();
while (remainingBytes > 0)
{
auto const n = std::min(output.size(), remainingBytes);
writer_(output.data(), n);
remainingBytes -= n;
}
}

void Benchmark::runAll()
{
auto buffer = make_unique<Buffer>(min(static_cast<size_t>(64u), testSizeMB_));
Expand All @@ -78,30 +90,19 @@ void Benchmark::runAll()
test->setup(width_, height_);
test->run(*buffer);

auto const output = buffer->output();
auto const totalSizeBytes = testSizeMB_ * 1024 * 1024;
auto const beginTime = steady_clock::now();
auto remainingBytes = totalSizeBytes;
writeOutput(*buffer);
auto const diff = duration_cast<milliseconds>(steady_clock::now() - beginTime);
while (diff < 1s)
{
while (remainingBytes > 0)
{
auto const n = std::min(output.size(), remainingBytes);
writer_(output.data(), n);
remainingBytes -= n;
}
}

results_.emplace_back(Result { *test, diff, totalSizeBytes });
results_.emplace_back(*test, diff, totalSizeBytes());

buffer->clear();
test->teardown(*buffer);
if (buffer->empty())
continue;

writer_(buffer->output().data(), buffer->output().size());
buffer->clear();
if (!buffer->empty())
{
writer_(buffer->output().data(), buffer->output().size());
buffer->clear();
}
}
}
//
Expand Down
4 changes: 4 additions & 0 deletions libtermbench/termbench.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,11 @@ class Benchmark

std::vector<Result> const& results() const noexcept { return results_; }

[[constexpr]] size_t totalSizeBytes() const noexcept { return testSizeMB_ * 1024 * 1024; }

private:
void writeOutput(Buffer const& testBuffer);

std::function<void(char const*, size_t)> writer_;
std::function<void(Test const&)> beforeTest_;
size_t testSizeMB_;
Expand Down
73 changes: 57 additions & 16 deletions scripts/Xvfb-bench-run.sh
Original file line number Diff line number Diff line change
@@ -1,30 +1,71 @@
#!/usr/bin/env bash

#
# Usage: Xvfb-contour-run.sh <contour-args>
# Usage: Xvfb-bench-run.sh <path-to-tb-executable>

set -x
TB_BIN="${1:-${TB_BIN}}"
CONTOUR_BIN="${CONTOUR_BIN:-contour}"
KITTY_BIN="${KITTY_BIN:-kitty}"
XTERM_BIN="${XTERM_BIN:-xterm}"
ALACRITTY_BIN="${ALACRITTY_BIN:-alacritty}"
FB_DISPLAY="${FB_DISPLAY:-:99}"

OUTPUT_DIR="${PWD}"

if [[ "$TB_BIN" == "" ]]; then
echo "Usage: $0 <path-to-tb-executable>"
exit 1
fi

function require_bin() {
local tool="${1}"
if ! which "${tool}" >/dev/null; then
echo 1>&2 "$0: Could not find the required tool ${tool}."
exit 1
fi
}

require_bin Xvfb
require_bin "${TB_BIN}"
require_bin "${CONTOUR_BIN}"
require_bin "${KITTY_BIN}"
require_bin "${XTERM_BIN}"
require_bin "${ALACRITTY_BIN}"

export TB_BIN=$(realpath $TB_BIN)
export DISPLAY=${FB_DISPLAY}
export LIBGL_ALWAYS_SOFTWARE="${LIBGL_ALWAYS_SOFTWARE:-true}"

LIBGL_ALWAYS_SOFTWARE="${LIBGL_ALWAYS_SOFTWARE:-true}"
DISPLAY=:99
export LIBGL_ALWAYS_SOFTWARE
export DISPLAY
function program_exit() {
local exit_code=$1
if [[ "$GITHUB_OUTPUT" != "" ]]; then
echo "exitCode=$exit_code" >> "$GITHUB_OUTPUT"
fi
exit $exit_code
}

function bench_terminal() {
printf "\033[1m==> Running terminal: $1\033[m\n"
local terminal_name=$(basename $1)
time "${@}" -e "${TB_BIN}" --stdout-fastpath --column-by-column --output "${OUTPUT_DIR}/${terminal_name}_results"
local exit_code=$?
printf "\033[1m==> Terminal exit code: $exit_code\033[m\n"
if [[ $exit_code -ne 0 ]]; then
program_exit $exit_code
fi
}

set -x

Xvfb $DISPLAY -screen 0 1280x1024x24 &
XVFB_PID=$!
trap "kill $XVFB_PID" EXIT

sleep 3

TB_BIN=$PWD/build/tb/tb
bench_terminal "${CONTOUR_BIN}" display ${DISPLAY}
bench_terminal "${KITTY_BIN}"
bench_terminal "${XTERM_BIN}" -display ${DISPLAY}
bench_terminal "${ALACRITTY_BIN}"

contour display ${DISPLAY} $TB_BIN --output contour_results
mv $HOME/contour_results .
kitty -e $TB_BIN --output kitty_results
xterm -display ${DISPLAY} -e $TB_BIN --output xterm_results
alacritty -e $TB_BIN --output alacritty_results

if [[ "$GITHUB_OUTPUT" != "" ]]; then
echo "exitCode=$?" >> "$GITHUB_OUTPUT"
fi
program_exit 0
7 changes: 7 additions & 0 deletions tb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@ set_target_properties(tb PROPERTIES

install(TARGETS tb RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

add_custom_target(Xvfb-bench-run
COMMAND ${CMAKE_SOURCE_DIR}/scripts/Xvfb-bench-run.sh $<TARGET_FILE:tb>
VERBATIM
USES_TERMINAL
DEPENDS tb
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
54 changes: 39 additions & 15 deletions tb/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,21 @@

using std::cerr;
using std::cout;
using std::stoul;
using std::tuple;

using namespace std::string_view_literals;
using namespace std::placeholders;

#if !defined(_WIN32)
#include <sys/ioctl.h>
#include <sys/stat.h>

#include <unistd.h>
#else
#include <Windows.h>
#endif

#define STDOUT_FASTPATH_FD 3

namespace
{
std::pair<unsigned short, unsigned short> getTerminalSize() noexcept
Expand All @@ -45,7 +46,7 @@ std::pair<unsigned short, unsigned short> getTerminalSize() noexcept

#if !defined(_WIN32)
winsize ws;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) < 0)
return DefaultSize;
return { ws.ws_col, ws.ws_row };
#else
Expand All @@ -58,6 +59,7 @@ void nullWrite(char const*, size_t)
{
}

template <const std::size_t StdoutFileNo>
void chunkedWriteToStdout(char const* _data, size_t _size)
{
auto constexpr PageSize = 4096; // 8192;
Expand All @@ -70,7 +72,7 @@ void chunkedWriteToStdout(char const* _data, size_t _size)
while (_size >= PageSize)
{
#if !defined(_WIN32)
auto const n = write(STDOUT_FILENO, _data, PageSize);
auto const n = write(StdoutFileNo, _data, PageSize);
if (n < 0)
perror("write");
_data += n;
Expand All @@ -83,7 +85,7 @@ void chunkedWriteToStdout(char const* _data, size_t _size)
#if !defined(_WIN32)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
write(STDOUT_FILENO, _data, _size);
write(StdoutFileNo, _data, _size);
#pragma GCC diagnostic pop
#else
WriteConsoleA(stdoutHandle, _data, static_cast<DWORD>(_size), &nwritten, nullptr);
Expand All @@ -104,6 +106,8 @@ int main(int argc, char const* argv[])
auto [width, height] = getTerminalSize();
size_t testSizeMB = 32;
bool nullSink = false;
bool stdoutFastPath = false;
bool columnByColumn = false;
std::string fileout {};

for (int i = 1; i < argc; ++i)
Expand All @@ -113,10 +117,24 @@ int main(int argc, char const* argv[])
cout << std::format("Using null-sink.\n");
nullSink = true;
}
else if (argv[i] == "--stdout-fastpath"sv)
{
#if !defined(_WIN32)
struct stat st;
stdoutFastPath = fstat(STDOUT_FASTPATH_FD, &st) == 0;
#else
std::cout << std::format("Ignoring {}\n", argv[i]);
#endif
}
else if (argv[i] == "--column-by-column"sv)
{
cout << std::format("Enabling column-by-column tests.\n");
columnByColumn = true;
}
else if (argv[i] == "--size"sv && i + 1 < argc)
{
++i;
testSizeMB = static_cast<size_t>(stoul(argv[i]));
testSizeMB = static_cast<size_t>(std::stoul(argv[i]));
}
else if (argv[i] == "--help"sv || argv[i] == "-h"sv)
{
Expand All @@ -135,7 +153,11 @@ int main(int argc, char const* argv[])
}
}

contour::termbench::Benchmark tb { nullSink ? nullWrite : chunkedWriteToStdout,
auto const writer = nullSink ? nullWrite
: stdoutFastPath ? chunkedWriteToStdout<STDOUT_FASTPATH_FD>
: chunkedWriteToStdout<STDOUT_FILENO>;

contour::termbench::Benchmark tb { writer,
testSizeMB, // MB per test
width,
height };
Expand All @@ -146,14 +168,16 @@ int main(int argc, char const* argv[])
tb.add(contour::termbench::tests::sgr_fg_lines());
tb.add(contour::termbench::tests::sgr_fgbg_lines());
tb.add(contour::termbench::tests::binary());
// tb.add(contour::termbench::tests::binary());
constexpr size_t Max_lines { 200 };
for (size_t i = 0; i < Max_lines; ++i)
tb.add(contour::termbench::tests::ascii_line(i));
for (size_t i = 0; i < Max_lines; ++i)
tb.add(contour::termbench::tests::sgr_line(i));
for (size_t i = 0; i < Max_lines; ++i)
tb.add(contour::termbench::tests::sgrbg_line(i));
if (columnByColumn)
{
constexpr size_t Max_lines { 200 };
for (size_t i = 0; i < Max_lines; ++i)
tb.add(contour::termbench::tests::ascii_line(i));
for (size_t i = 0; i < Max_lines; ++i)
tb.add(contour::termbench::tests::sgr_line(i));
for (size_t i = 0; i < Max_lines; ++i)
tb.add(contour::termbench::tests::sgrbg_line(i));
}

cout << "\033[8;30;100t";
cout.flush();
Expand Down

0 comments on commit e2246d4

Please sign in to comment.