blob: c8832c4cde5f372b82773f4e5e6e4ab8beb2dea4 [file] [log] [blame]
// Copyright 2022 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_CPP_SEND_EVENT_BENCHMARK_UTIL_H_
#define SRC_TESTS_BENCHMARKS_FIDL_CPP_SEND_EVENT_BENCHMARK_UTIL_H_
#include <lib/fidl/cpp/channel.h>
#include <lib/sync/cpp/completion.h>
#include <zircon/status.h>
#include <zircon/types.h>
#include <algorithm>
#include <thread>
#include <type_traits>
#include <perftest/perftest.h>
namespace cpp_benchmarks {
template <typename ProtocolType, typename BuilderFunc>
bool SendEventBenchmark(perftest::RepeatState* state, BuilderFunc builder) {
using FidlType = std::invoke_result_t<BuilderFunc>;
static_assert(fidl::IsFidlType<FidlType>::value, "FIDL type required");
state->DeclareStep("Setup/WallTime");
state->DeclareStep("SendEvent/WallTime");
state->DeclareStep("Teardown/WallTime");
auto endpoints = fidl::CreateEndpoints<ProtocolType>();
ZX_ASSERT(endpoints.is_ok());
class EventHandler : public fidl::AsyncEventHandler<ProtocolType> {
public:
EventHandler(perftest::RepeatState* state) : state_(state) {}
void Send(fidl::Event<typename ProtocolType::Send>& event) override {
state_->NextStep(); // End: SendEvent. Begin: Teardown.
completion_.Signal();
}
libsync::Completion& completion() { return completion_; }
private:
perftest::RepeatState* state_;
libsync::Completion completion_;
};
async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
loop.StartThread();
EventHandler event_handler(state);
fidl::Client<ProtocolType> client;
libsync::Completion bound;
async::PostTask(loop.dispatcher(), [&]() {
client.Bind(std::move(endpoints->client), loop.dispatcher(), &event_handler);
bound.Signal();
});
ZX_ASSERT(ZX_OK == bound.Wait());
while (state->KeepRunning()) {
FidlType aligned_value = builder();
state->NextStep(); // End: Setup. Begin: SendEvent.
auto result = fidl::SendEvent(std::move(endpoints->server))->Send(std::move(aligned_value));
ZX_ASSERT(result.is_ok());
event_handler.completion().Wait();
event_handler.completion().Reset();
}
libsync::Completion destroyed;
async::PostTask(loop.dispatcher(),
[client = std::move(client), &destroyed]() { destroyed.Signal(); });
ZX_ASSERT(ZX_OK == destroyed.Wait());
return true;
}
} // namespace cpp_benchmarks
#endif // SRC_TESTS_BENCHMARKS_FIDL_CPP_SEND_EVENT_BENCHMARK_UTIL_H_