blob: da5b669939d08cdc08dacd8e6c5c644ecc725829 [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.
#include <fuchsia/zircon/benchmarks/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/zx/channel.h>
#include <lib/zx/handle.h>
#include <functional>
#include <thread>
#include <vector>
#include "assert.h"
#include "test_runner.h"
// This file benchmarks a common FIDL server using a libasync dispatch loop.
// In each benchmark iteration, a single thread enqueues N messages (the
// "client write" phase), and then runs an async loop to idle ("server
// process" phase), where each message will be handled by a null callback.
// The server process phase exercises Zircon's channel waiting and reading
// mechanisms, trivial FIDL message decoding, and the libasync dispatch loop.
namespace {
class NotificationImpl : public fuchsia::zircon::benchmarks::Notification {
void Notify() override {}
bool AsyncLoopProcessBatch(uint32_t count, perftest::RepeatState* state) {
// Set up client.
zx::channel server, client;
ASSERT_OK(zx::channel::create(0, &server, &client));
fuchsia::zircon::benchmarks::NotificationSyncPtr service;
// Set up server.
NotificationImpl service_impl;
async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
fidl::Binding<fuchsia::zircon::benchmarks::Notification> binding(&service_impl,
binding.set_error_handler([&loop](zx_status_t status) { loop.Quit(); });
// Start the benchmark.
while (state->KeepRunning()) {
// Enqueue 'count' messages.
for (uint32_t i = 0; i < count; i++) {
// Process all messages.'
return true;
void RegisterTests() {
// Return a benchmark function the processes "count" messages per batch.
auto AsyncLoopProcessBatchN = [](uint32_t count) {
return [count](perftest::RepeatState* state) { return AsyncLoopProcessBatch(count, state); };
perftest::RegisterTest("AsyncLoopProcessBatch/1", AsyncLoopProcessBatchN(1));
perftest::RegisterTest("AsyncLoopProcessBatch/2", AsyncLoopProcessBatchN(2));
perftest::RegisterTest("AsyncLoopProcessBatch/4", AsyncLoopProcessBatchN(4));
perftest::RegisterTest("AsyncLoopProcessBatch/8", AsyncLoopProcessBatchN(8));
perftest::RegisterTest("AsyncLoopProcessBatch/16", AsyncLoopProcessBatchN(16));
} // namespace