blob: 8fa684c9a42698f55f0943df0b27716d0f971429 [file] [log] [blame]
// 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.
#ifndef SRC_TESTS_BENCHMARKS_FIDL_REFERENCE_DECODE_BENCHMARK_UTIL_H_
#define SRC_TESTS_BENCHMARKS_FIDL_REFERENCE_DECODE_BENCHMARK_UTIL_H_
#include <lib/fidl/llcpp/arena.h>
#include <lib/fidl/llcpp/message.h>
#include <zircon/fidl.h>
#include <zircon/status.h>
#include <iomanip>
#include <iostream>
#include <vector>
#include <perftest/perftest.h>
namespace decode_benchmark_util {
template <typename BuilderFunc, typename DecodeFunc>
bool DecodeBenchmark(perftest::RepeatState* state, BuilderFunc builder, DecodeFunc decode) {
using FidlType = std::invoke_result_t<BuilderFunc, fidl::AnyArena&>;
static_assert(fidl::IsFidlType<FidlType>::value, "FIDL type required");
fidl::Arena<65536> allocator;
FidlType aligned_value = builder(allocator);
fidl::unstable::OwnedEncodedMessage<FidlType> encoded(fidl::internal::WireFormatVersion::kV2,
&aligned_value);
ZX_ASSERT(encoded.ok());
state->DeclareStep("Setup/WallTime");
state->DeclareStep("Decode/WallTime");
state->DeclareStep("Teardown/WallTime");
fidl::OutgoingMessage::CopiedBytes bytes;
while (state->KeepRunning()) {
bytes = encoded.GetOutgoingMessage().CopyBytes();
state->NextStep(); // End: Setup. Begin: Decode.
const char* error;
if (!decode(bytes.data(), bytes.size(), nullptr, 0, &error)) {
std::cout << "error in decode benchmark: " << error << std::endl;
return false;
}
state->NextStep(); // End: Decode. Begin: Teardown.
}
// Reencode the decoded result and compare against the initial (expected) encode_result.
fidl::unstable::OwnedEncodedMessage<FidlType> reencoded(
fidl::internal::WireFormatVersion::kV2, reinterpret_cast<FidlType*>(bytes.data()));
if (!reencoded.ok()) {
std::cout << "fidl::Encode failed with error: " << reencoded.error() << std::endl;
return false;
}
auto reencoded_bytes = reencoded.GetOutgoingMessage().CopyBytes();
auto encoded_bytes = encoded.GetOutgoingMessage().CopyBytes();
if (encoded_bytes.size() != reencoded_bytes.size()) {
std::cout << "output size mismatch - reencoded size was " << encoded_bytes.size()
<< " but expected encode result size was" << encoded_bytes.size() << std::endl;
return false;
}
bool success = true;
for (uint32_t i = 0; i < encoded_bytes.size(); ++i) {
if (encoded_bytes.data()[i] != reencoded_bytes.data()[i]) {
std::cout << "At offset " << i << " reencoded got 0x" << std::setw(2) << std::setfill('0')
<< std::hex << int(reencoded_bytes.data()[i]) << " but expected was 0x"
<< int(encoded_bytes.data()[i]) << std::dec << std::endl;
success = false;
}
}
return success;
}
} // namespace decode_benchmark_util
#endif // SRC_TESTS_BENCHMARKS_FIDL_REFERENCE_DECODE_BENCHMARK_UTIL_H_