blob: 3793df56f93909419c38eaecd2477977ee0ac126 [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/internal.h>
#include <zircon/fidl.h>
#include <zircon/status.h>
#include <iomanip>
#include <iostream>
#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>;
static_assert(fidl::IsFidlType<FidlType>::value, "FIDL type required");
fidl::aligned<FidlType> aligned_value = builder();
fidl::OwnedEncodedMessage<FidlType> encoded(&aligned_value.value);
ZX_ASSERT(encoded.ok() && encoded.error() == nullptr);
fidl::OutgoingMessage& encoded_message = encoded.GetOutgoingMessage();
state->DeclareStep("Setup/WallTime");
state->DeclareStep("Decode/WallTime");
state->DeclareStep("Teardown/WallTime");
std::vector<uint8_t> test_data(encoded_message.byte_actual());
while (state->KeepRunning()) {
memcpy(test_data.data(), encoded_message.bytes(), encoded_message.byte_actual());
state->NextStep(); // End: Setup. Begin: Decode.
const char* error;
if (!decode(&test_data[0], test_data.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::OwnedEncodedMessage<FidlType> reencoded(reinterpret_cast<FidlType*>(test_data.data()));
if (!reencoded.ok()) {
std::cout << "fidl::Encode failed with error: " << reencoded.error() << std::endl;
return false;
}
fidl::OutgoingMessage& reencoded_message = reencoded.GetOutgoingMessage();
if (encoded_message.byte_actual() != reencoded_message.byte_actual()) {
std::cout << "output size mismatch - reencoded size was " << reencoded_message.byte_actual()
<< " but expected encode result size was" << encoded_message.byte_actual()
<< std::endl;
return false;
}
bool success = true;
for (uint32_t i = 0; i < encoded_message.byte_actual(); ++i) {
if (encoded_message.bytes()[i] != reencoded_message.bytes()[i]) {
std::cout << "At offset " << i << " reencoded got 0x" << std::setw(2) << std::setfill('0')
<< std::hex << int(reencoded_message.bytes()[i]) << " but expected was 0x"
<< int(encoded_message.bytes()[i]) << std::dec << std::endl;
success = false;
}
}
return success;
}
} // namespace decode_benchmark_util
#endif // SRC_TESTS_BENCHMARKS_FIDL_REFERENCE_DECODE_BENCHMARK_UTIL_H_