blob: 37d9848e9f24c4c3cab7480d58c638c532b75d2a [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/zx/socket.h>
#include <vector>
#include <fbl/string_printf.h>
#include <perftest/perftest.h>
#include "assert.h"
namespace {
// Measure the times taken to enqueue and then dequeue some bytes from a
// Zircon socket, on a single thread. This does not involve any
// cross-thread wakeups. The |socket_flags| can be used to control whether the
// socket is a stream or a datagram, and |queued| represents how many messages
// to write to the socket before beginning the benchmark. Having messages queued
// on the socket allows for testing scenarios where the socket stays non-empty,
// versus transitions from empty to non-empty and back on each iteration.
bool SocketWriteReadTest(perftest::RepeatState* state, uint32_t socket_flags, uint32_t message_size,
uint32_t queued) {
state->DeclareStep("write");
state->DeclareStep("read");
zx::socket socket1;
zx::socket socket2;
ASSERT_OK(zx::socket::create(socket_flags, &socket1, &socket2));
std::vector<char> buffer(message_size);
for (uint32_t i = 0; i < queued; i++) {
size_t bytes_written;
ASSERT_OK(socket1.write(0, buffer.data(), buffer.size(), &bytes_written));
ZX_ASSERT(bytes_written == buffer.size());
}
while (state->KeepRunning()) {
size_t bytes_written;
ASSERT_OK(socket1.write(0, buffer.data(), buffer.size(), &bytes_written));
ZX_ASSERT(bytes_written == buffer.size());
state->NextStep();
size_t bytes_read;
ASSERT_OK(socket2.read(0, buffer.data(), buffer.size(), &bytes_read));
ZX_ASSERT(bytes_read == buffer.size());
}
return true;
}
void RegisterTests() {
// Since stream payloads can coexist in different MBufChains internally we want to test cases
// where messages always sit inside a buffer, will stride across a single buffer boundary, and
// require multiple buffers.
static const unsigned kStreamMessageSizesInBytes[] = {
64,
1 * 1024,
64 * 1024,
};
// Datagrams always occupy their own MBufChain, so just test a very small and very large message
// to show baseline costs versus copying overhead.
static const unsigned kDatagramMessageSizesInBytes[] = {
64,
64 * 1024,
};
static const unsigned kMessagesToQueue[] = {
0,
1,
};
for (auto message_size : kStreamMessageSizesInBytes) {
for (auto queued_messages : kMessagesToQueue) {
auto name = fbl::StringPrintf("Socket/Stream/WriteRead/%ubytes/%uqueued", message_size,
queued_messages);
perftest::RegisterTest(name.c_str(), SocketWriteReadTest, ZX_SOCKET_STREAM, message_size,
queued_messages);
}
}
for (auto message_size : kDatagramMessageSizesInBytes) {
for (auto queued_messages : kMessagesToQueue) {
auto name = fbl::StringPrintf("Socket/Datagram/WriteRead/%ubytes/%uqueued", message_size,
queued_messages);
perftest::RegisterTest(name.c_str(), SocketWriteReadTest, ZX_SOCKET_DATAGRAM, message_size,
queued_messages);
}
}
}
PERFTEST_CTOR(RegisterTests)
} // namespace