| // Copyright 2020 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/stream.h> |
| #include <lib/zx/vmo.h> |
| |
| #include <algorithm> |
| #include <vector> |
| |
| #include <fbl/string_printf.h> |
| #include <perftest/perftest.h> |
| |
| #include "assert.h" |
| |
| namespace { |
| |
| // Measure the time taken to write to a zx::stream for various sizes of writes and with various |
| // length iovecs. |
| bool StreamWriteAtTest(perftest::RepeatState* state, uint32_t message_size, size_t vector_count) { |
| state->SetBytesProcessedPerRun(message_size); |
| |
| zx::vmo vmo; |
| ASSERT_OK(zx::vmo::create(std::max<size_t>(PAGE_SIZE, message_size), 0, &vmo)); |
| size_t content_size = message_size; |
| ASSERT_OK(vmo.set_property(ZX_PROP_VMO_CONTENT_SIZE, &content_size, sizeof(content_size))); |
| |
| zx::stream stream; |
| ASSERT_OK(zx::stream::create(ZX_STREAM_MODE_WRITE, vmo, 0, &stream)); |
| std::vector<char> buffer(message_size); |
| zx_cprng_draw(buffer.data(), buffer.size()); |
| |
| std::vector<zx_iovec_t> vector(vector_count); |
| size_t buffer_capacity = buffer.size() / vector_count; |
| for (size_t i = 0; i < vector_count; ++i) { |
| vector[i].buffer = buffer.data() + i * buffer_capacity; |
| vector[i].capacity = buffer_capacity; |
| } |
| |
| while (state->KeepRunning()) { |
| size_t bytes_written; |
| ASSERT_OK(stream.writev_at(0, 0, vector.data(), vector_count, &bytes_written)); |
| ZX_ASSERT(bytes_written == message_size); |
| } |
| return true; |
| } |
| |
| // Measure the time taken to read from a zx::stream for various sizes of reads and with various |
| // length iovecs. |
| bool StreamReadAtTest(perftest::RepeatState* state, uint32_t message_size, size_t vector_count) { |
| state->SetBytesProcessedPerRun(message_size); |
| |
| zx::vmo vmo; |
| ASSERT_OK(zx::vmo::create(std::max<size_t>(PAGE_SIZE, message_size), 0, &vmo)); |
| size_t content_size = message_size; |
| ASSERT_OK(vmo.set_property(ZX_PROP_VMO_CONTENT_SIZE, &content_size, sizeof(content_size))); |
| |
| zx::stream stream; |
| ASSERT_OK(zx::stream::create(ZX_STREAM_MODE_READ, vmo, 0, &stream)); |
| std::vector<char> buffer(message_size); |
| zx_cprng_draw(buffer.data(), buffer.size()); |
| |
| ASSERT_OK(vmo.write(buffer.data(), 0, buffer.size())); |
| |
| std::vector<zx_iovec_t> vector(vector_count); |
| size_t buffer_capacity = buffer.size() / vector_count; |
| for (size_t i = 0; i < vector_count; ++i) { |
| vector[i].buffer = buffer.data() + i * buffer_capacity; |
| vector[i].capacity = buffer_capacity; |
| } |
| |
| while (state->KeepRunning()) { |
| size_t bytes_read; |
| ASSERT_OK(stream.readv_at(0, 0, vector.data(), vector_count, &bytes_read)); |
| ZX_ASSERT(bytes_read == message_size); |
| } |
| return true; |
| } |
| |
| void RegisterTests() { |
| static const unsigned kMessageSizesInBytes[] = { |
| 64, |
| 1 * 1024, |
| 32 * 1024, |
| 64 * 1024, |
| }; |
| for (auto message_size : kMessageSizesInBytes) { |
| auto name = fbl::StringPrintf("Stream/WriteAt/%ubytes", message_size); |
| perftest::RegisterTest(name.c_str(), StreamWriteAtTest, message_size, 1u); |
| name = fbl::StringPrintf("Stream/WriteAt<64>/%ubytes", message_size); |
| perftest::RegisterTest(name.c_str(), StreamWriteAtTest, message_size, 64u); |
| |
| name = fbl::StringPrintf("Stream/ReadAt/%ubytes", message_size); |
| perftest::RegisterTest(name.c_str(), StreamReadAtTest, message_size, 1u); |
| name = fbl::StringPrintf("Stream/ReadAt<64>/%ubytes", message_size); |
| perftest::RegisterTest(name.c_str(), StreamReadAtTest, message_size, 64u); |
| } |
| } |
| PERFTEST_CTOR(RegisterTests); |
| |
| } // namespace |