// Copyright 2017 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 <pthread.h>
#include <thread>
#include <vector>

#include <fuchsia/zircon/benchmarks/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/spawn.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/port.h>

#include "lib/fidl/cpp/binding.h"
#include "lib/fxl/arraysize.h"
#include "lib/fxl/logging.h"

#include "round_trips.h"
#include "test_runner.h"

// This file measures two things:
//
// 1) The round-trip time of various operations, including Zircon kernel IPC
// primitives.  This measures the latency of sending a request to another thread
// or process and receiving a reply back.  In this case, there's little
// opportunity for concurrency between the two threads.
//
// 2) The throughput of IPC operations.  This is similar to measuring the
// round-trip time, except that instead of sending and receiving one message,
// the main thread sends N messages and then waits for N messages in reply.
// This allows for more concurrency between the two threads.  Currently we only
// test this for Zircon channels.
//
// Note that the first case is a special case of the second case, with N=1.
//
// These tests generally use the same IPC primitive in both directions
// (i.e. from client to server and from server to client) for sending and
// receiving wakeups.  There are a couple of reasons for that:
//
//  * This allows us to estimate the one-way latency of the IPC primitive
//    by dividing the round-trip latency by 2.
//  * This keeps the number of tests manageable.  If we mixed the
//    primitives, the number of possible combinations would be O(n^2) in
//    the number of primitives.  (For example, we could signal using a
//    channel in one direction and a futex in the other direction.)
//
// An exception is zx_channel_call(), which generally can't be used by a
// server process for receiving requests.

namespace {

// Block and read a message of size |msg->size()| into |msg| from a channel.
// Returns false if the channel's peer was closed.
bool ChannelRead(zx_handle_t channel, std::vector<uint8_t>* msg) {
  zx_signals_t observed;
  zx_status_t status =
      zx_object_wait_one(channel, ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
                         ZX_TIME_INFINITE, &observed);
  FXL_CHECK(status == ZX_OK);
  if (observed & ZX_CHANNEL_PEER_CLOSED)
    return false;

  uint32_t bytes_read;
  status = zx_channel_read(channel, 0, msg->data(), nullptr, msg->size(), 0,
                           &bytes_read, nullptr);
  FXL_CHECK(status == ZX_OK);
  FXL_CHECK(bytes_read == msg->size());
  return true;
}

// Block and read |count| messages of size |msg->size()| into |msg| from a
// channel.  Returns false if the channel's peer was closed.
bool ChannelReadMultiple(zx_handle_t channel, uint32_t count,
                         std::vector<uint8_t>* msg) {
  for (uint32_t i = 0; i < count; ++i) {
    if (!ChannelRead(channel, msg))
      return false;
  }
  return true;
}

// Serve requests on a channel: read |count| messages of size |size| and write
// |count| replies.
void ChannelServe(zx_handle_t channel, uint32_t count, uint32_t size) {
  std::vector<uint8_t> msg(size);
  for (;;) {
    if (!ChannelReadMultiple(channel, count, &msg))
      break;
    for (uint32_t i = 0; i < count; ++i) {
      zx_status_t status =
          zx_channel_write(channel, 0, msg.data(), msg.size(), nullptr, 0);
      FXL_CHECK(status == ZX_OK);
    }
  }
}

typedef void (*ThreadFunc)(std::vector<zx_handle_t> handles);
ThreadFunc GetThreadFunc(const char* name);

enum MultiProc {
  SingleProcess = 1,
  MultiProcess = 2,
};

// Helper class for launching a thread or a subprocess.
class ThreadOrProcess {
 public:
  ~ThreadOrProcess() {
    if (thread_.joinable())
      thread_.join();
    if (subprocess_ != ZX_HANDLE_INVALID) {
      // Join the process.
      FXL_CHECK(zx_object_wait_one(subprocess_, ZX_PROCESS_TERMINATED,
                                   ZX_TIME_INFINITE, nullptr) == ZX_OK);
      zx_handle_close(subprocess_);
    }
  }

  void Launch(const char* func_name, zx_handle_t* handles,
              uint32_t handle_count, MultiProc multiproc) {
    if (multiproc == MultiProcess) {
      const char* executable_path =
          "/pkgfs/packages/zircon_benchmarks/0/test/zircon_benchmarks";
      const char* args[] = {executable_path, "--subprocess", func_name,
                            nullptr};
      fdio_spawn_action_t actions[handle_count + 1];
      for (uint32_t i = 0; i < handle_count; ++i) {
        actions[i].action = FDIO_SPAWN_ACTION_ADD_HANDLE;
        actions[i].h.id = PA_HND(PA_USER0, i);
        actions[i].h.handle = handles[i];
      }
      actions[handle_count].action = FDIO_SPAWN_ACTION_SET_NAME;
      actions[handle_count].name.data = "test-process";

      char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
      if (fdio_spawn_etc(ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL,
                         executable_path, args, nullptr, handle_count + 1,
                         actions, &subprocess_, err_msg) != ZX_OK) {
        FXL_LOG(FATAL) << "Subprocess launch failed: " << err_msg;
      }
    } else {
      std::vector<zx_handle_t> handle_vector(handles, handles + handle_count);
      thread_ = std::thread(GetThreadFunc(func_name), handle_vector);
    }
  }

 private:
  std::thread thread_;
  zx_handle_t subprocess_ = ZX_HANDLE_INVALID;
};

// Test IPC round trips and/or throughput using Zircon channels where the client
// and server both use zx_object_wait_one() to wait.
class BasicChannelTest {
 public:
  explicit BasicChannelTest(MultiProc multiproc, uint32_t msg_count,
                            uint32_t msg_size)
      : args_({msg_count, msg_size}), msg_(args_.msg_size) {
    zx_handle_t server;
    FXL_CHECK(zx_channel_create(0, &server, &client_) == ZX_OK);
    thread_or_process_.Launch("BasicChannelTest::ThreadFunc", &server, 1,
                              multiproc);

    // Pass the test arguments to the other thread.
    zx_status_t status =
        zx_channel_write(client_, 0, &args_, sizeof(args_), nullptr, 0);
    FXL_CHECK(status == ZX_OK);
  }

  ~BasicChannelTest() { zx_handle_close(client_); }

  static void ThreadFunc(std::vector<zx_handle_t> handles) {
    FXL_CHECK(handles.size() == 1);
    zx_handle_t channel = handles[0];
    Args args;
    GetArgs(channel, &args);
    ChannelServe(channel, args.msg_count, args.msg_size);
    zx_handle_close(channel);
  }

  void Run() {
    for (unsigned i = 0; i < args_.msg_count; ++i) {
      FXL_CHECK(zx_channel_write(client_, 0, msg_.data(), msg_.size(), nullptr,
                                 0) == ZX_OK);
    }
    FXL_CHECK(ChannelReadMultiple(client_, args_.msg_count, &msg_));
  }

 private:
  // Holds the test arguments sent over a channel.
  struct Args {
    uint32_t msg_count;
    uint32_t msg_size;
  };

  // Reads test arguments from |channel| and stores them in |args|.
  static void GetArgs(zx_handle_t channel, Args* args) {
    std::vector<uint8_t> msg(sizeof(*args));
    FXL_CHECK(ChannelRead(channel, &msg));
    *args = *reinterpret_cast<Args*>(msg.data());
  }

  const Args args_;
  std::vector<uint8_t> msg_;
  zx_handle_t client_;
  ThreadOrProcess thread_or_process_;
};

// Test IPC round trips using Zircon channels where the client and server
// both use Zircon ports to wait, using ZX_WAIT_ASYNC_ONCE.
class ChannelPortTest {
 public:
  explicit ChannelPortTest(MultiProc multiproc) {
    zx_handle_t server;
    FXL_CHECK(zx_channel_create(0, &server, &client_) == ZX_OK);
    thread_or_process_.Launch("ChannelPortTest::ThreadFunc", &server, 1,
                              multiproc);
    FXL_CHECK(zx_port_create(0, &client_port_) == ZX_OK);
  }

  ~ChannelPortTest() {
    zx_handle_close(client_);
    zx_handle_close(client_port_);
  }

  static bool ChannelPortRead(zx_handle_t channel, zx_handle_t port,
                              uint32_t* msg) {
    FXL_CHECK(zx_object_wait_async(channel, port, 0,
                                   ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
                                   ZX_WAIT_ASYNC_ONCE) == ZX_OK);

    zx_port_packet_t packet;
    FXL_CHECK(zx_port_wait(port, ZX_TIME_INFINITE, &packet) == ZX_OK);
    if (packet.signal.observed & ZX_CHANNEL_PEER_CLOSED)
      return false;

    uint32_t bytes_read;
    FXL_CHECK(zx_channel_read(channel, 0, msg, nullptr, sizeof(*msg), 0,
                              &bytes_read, nullptr) == ZX_OK);
    FXL_CHECK(bytes_read == sizeof(*msg));
    return true;
  }

  static void ThreadFunc(std::vector<zx_handle_t> handles) {
    FXL_CHECK(handles.size() == 1);
    zx_handle_t channel = handles[0];

    zx_handle_t port;
    FXL_CHECK(zx_port_create(0, &port) == ZX_OK);

    for (;;) {
      uint32_t msg;
      if (!ChannelPortRead(channel, port, &msg))
        break;
      FXL_CHECK(zx_channel_write(channel, 0, &msg, sizeof(msg), nullptr, 0) ==
                ZX_OK);
    }

    zx_handle_close(channel);
    zx_handle_close(port);
  }

  void Run() {
    uint32_t msg = 123;
    FXL_CHECK(zx_channel_write(client_, 0, &msg, sizeof(msg), nullptr, 0) ==
              ZX_OK);
    FXL_CHECK(ChannelPortRead(client_, client_port_, &msg));
  }

 private:
  zx_handle_t client_;
  zx_handle_t client_port_;
  ThreadOrProcess thread_or_process_;
};

// Test IPC round trips using Zircon channels where the server uses
// zx_object_wait_one() to wait (as with BasicChannelTest) but the client
// uses zx_channel_call() for the send+wait+read.
class ChannelCallTest {
 public:
  explicit ChannelCallTest(MultiProc multiproc) {
    zx_handle_t server;
    FXL_CHECK(zx_channel_create(0, &server, &client_) == ZX_OK);
    thread_or_process_.Launch("ChannelCallTest::ThreadFunc", &server, 1,
                              multiproc);

    msg_ = 0;
    args_.wr_bytes = reinterpret_cast<void*>(&msg_);
    args_.wr_handles = nullptr;
    args_.rd_bytes = reinterpret_cast<void*>(&reply_);
    args_.rd_handles = nullptr;
    args_.wr_num_bytes = sizeof(msg_);
    args_.wr_num_handles = 0;
    args_.rd_num_bytes = sizeof(reply_);
    args_.rd_num_handles = 0;
  }

  ~ChannelCallTest() { zx_handle_close(client_); }

  static void ThreadFunc(std::vector<zx_handle_t> handles) {
    FXL_CHECK(handles.size() == 1);
    zx_handle_t channel = handles[0];
    ChannelServe(channel, /* count= */ 1, /* size= */ 4);
    zx_handle_close(channel);
  }

  void Run() {
    uint32_t bytes_read;
    uint32_t handles_read;
    zx_status_t status = zx_channel_call(client_, 0, ZX_TIME_INFINITE, &args_,
                                         &bytes_read, &handles_read);
    FXL_CHECK(status == ZX_OK);
  }

 private:
  zx_handle_t client_;
  ThreadOrProcess thread_or_process_;
  uint32_t msg_;
  uint32_t reply_;
  zx_channel_call_args_t args_;
};

// Test IPC round trips using Zircon ports, where the client and server
// send each other user packets.  This is not a normal use case for ports,
// but it is useful for measuring the overhead of ports.
class PortTest {
 public:
  explicit PortTest(MultiProc multiproc) {
    FXL_CHECK(zx_port_create(0, &ports_[0]) == ZX_OK);
    FXL_CHECK(zx_port_create(0, &ports_[1]) == ZX_OK);

    zx_handle_t ports_dup[2];
    for (int i = 0; i < 2; ++i) {
      FXL_CHECK(zx_handle_duplicate(ports_[i], ZX_RIGHT_SAME_RIGHTS,
                                    &ports_dup[i]) == ZX_OK);
    }
    thread_or_process_.Launch("PortTest::ThreadFunc", ports_dup,
                              arraysize(ports_dup), multiproc);
  }

  ~PortTest() {
    // Tell the server to shut down.
    zx_port_packet_t packet = {};
    packet.type = ZX_PKT_TYPE_USER;
    packet.user.u32[0] = 1;
    FXL_CHECK(zx_port_queue(ports_[0], &packet) == ZX_OK);

    zx_handle_close(ports_[0]);
    zx_handle_close(ports_[1]);
  }

  static void ThreadFunc(std::vector<zx_handle_t> ports) {
    FXL_CHECK(ports.size() == 2);
    for (;;) {
      zx_port_packet_t packet;
      FXL_CHECK(zx_port_wait(ports[0], ZX_TIME_INFINITE, &packet) == ZX_OK);
      // Check for a request to shut down.
      if (packet.user.u32[0])
        break;
      FXL_CHECK(zx_port_queue(ports[1], &packet) == ZX_OK);
    }
    zx_handle_close(ports[0]);
    zx_handle_close(ports[1]);
  }

  void Run() {
    zx_port_packet_t packet = {};
    packet.type = ZX_PKT_TYPE_USER;
    FXL_CHECK(zx_port_queue(ports_[0], &packet) == ZX_OK);
    FXL_CHECK(zx_port_wait(ports_[1], ZX_TIME_INFINITE, &packet) == ZX_OK);
  }

 private:
  zx_handle_t ports_[2];
  ThreadOrProcess thread_or_process_;
};

// Helper object for signaling and waiting on a Zircon event object.  This
// uses a port for waiting on the event object.
class EventPortSignaler {
 public:
  EventPortSignaler() { FXL_CHECK(zx::port::create(0, &port_) == ZX_OK); }

  void set_event(zx::eventpair&& event) { event_ = std::move(event); }

  // Waits for the event to be signaled.  Returns true if it was signaled
  // by Signal() and false if the peer event object was closed.
  bool Wait() {
    FXL_CHECK(event_.wait_async(port_, 0,
                                ZX_USER_SIGNAL_0 | ZX_EVENTPAIR_PEER_CLOSED,
                                ZX_WAIT_ASYNC_ONCE) == ZX_OK);
    zx_port_packet_t packet;
    FXL_CHECK(port_.wait(zx::time::infinite(), &packet) == ZX_OK);
    if (packet.signal.observed & ZX_EVENTPAIR_PEER_CLOSED)
      return false;
    // Clear the signal bit.
    FXL_CHECK(event_.signal(ZX_USER_SIGNAL_0, 0) == ZX_OK);
    return true;
  }

  void Signal() {
    // Set a signal bit.
    FXL_CHECK(event_.signal_peer(0, ZX_USER_SIGNAL_0) == ZX_OK);
  }

 private:
  zx::eventpair event_;
  zx::port port_;
};

// Test the round trip time for waking up threads by signaling using Zircon
// event objects.  This uses ports for waiting on the events (rather than
// zx_object_wait_one()), because ports are the most general way to wait.
class EventPortTest {
 public:
  explicit EventPortTest(MultiProc multiproc) {
    zx::eventpair event1;
    zx::eventpair event2;
    FXL_CHECK(zx::eventpair::create(0, &event1, &event2) == ZX_OK);
    signaler_.set_event(std::move(event1));

    zx_handle_t event_arg = event2.release();
    thread_or_process_.Launch("EventPortTest::ThreadFunc", &event_arg, 1,
                              multiproc);
  }

  static void ThreadFunc(std::vector<zx_handle_t> handles) {
    FXL_CHECK(handles.size() == 1);

    EventPortSignaler signaler;
    signaler.set_event(zx::eventpair(handles[0]));
    while (signaler.Wait()) {
      signaler.Signal();
    }
  }

  void Run() {
    signaler_.Signal();
    FXL_CHECK(signaler_.Wait());
  }

 private:
  ThreadOrProcess thread_or_process_;
  EventPortSignaler signaler_;
};

// Helper object for signaling and waiting on a Zircon socket object.  This
// uses a port for waiting on the socket object.
class SocketPortSignaler {
 public:
  SocketPortSignaler() { FXL_CHECK(zx::port::create(0, &port_) == ZX_OK); }

  void set_socket(zx::socket&& socket) { socket_ = std::move(socket); }

  // Waits for the socket to be signaled: reads a byte from the socket.
  // Returns true if it was signaled by Signal() and false if it was
  // signaled by SignalExit().
  bool Wait() {
    FXL_CHECK(socket_.wait_async(port_, 0,
                                 ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED,
                                 ZX_WAIT_ASYNC_ONCE) == ZX_OK);
    zx_port_packet_t packet;
    FXL_CHECK(port_.wait(zx::time::infinite(), &packet) == ZX_OK);
    if (packet.signal.observed & ZX_SOCKET_PEER_CLOSED)
      return false;
    uint8_t message;
    size_t bytes_read = 0;
    FXL_CHECK(socket_.read(0, &message, 1, &bytes_read) == ZX_OK);
    FXL_CHECK(bytes_read == 1);
    return true;
  }

  // Signal the socket by writing a byte to it.
  void Signal() {
    uint8_t message = 0;
    size_t bytes_written = 0;
    FXL_CHECK(socket_.write(0, &message, 1, &bytes_written) == ZX_OK);
    FXL_CHECK(bytes_written == 1);
  }

 private:
  zx::socket socket_;
  zx::port port_;
};

// Test the round trip time for waking up threads by reading and writing
// bytes on Zircon socket objects.  This uses ports for waiting on the
// sockets (rather than zx_object_wait_one()), because ports are the most
// general way to wait.
class SocketPortTest {
 public:
  explicit SocketPortTest(MultiProc multiproc) {
    zx::socket socket1;
    zx::socket socket2;
    FXL_CHECK(zx::socket::create(0, &socket1, &socket2) == ZX_OK);
    signaler_.set_socket(std::move(socket1));

    zx_handle_t socket_arg = socket2.release();
    thread_or_process_.Launch("SocketPortTest::ThreadFunc", &socket_arg, 1,
                              multiproc);
  }

  static void ThreadFunc(std::vector<zx_handle_t> handles) {
    FXL_CHECK(handles.size() == 1);

    SocketPortSignaler signaler;
    signaler.set_socket(zx::socket(handles[0]));
    while (signaler.Wait()) {
      signaler.Signal();
    }
  }

  void Run() {
    signaler_.Signal();
    FXL_CHECK(signaler_.Wait());
  }

 private:
  ThreadOrProcess thread_or_process_;
  SocketPortSignaler signaler_;
};

// Implementation of FIDL interface for testing round trip IPCs.
class RoundTripServiceImpl
    : public fuchsia::zircon::benchmarks::RoundTripService {
 public:
  void RoundTripTest(uint32_t arg, RoundTripTestCallback callback) override {
    FXL_CHECK(arg == 123);
    callback(456);
  }
};

// Test IPC round trips using FIDL IPC.  This uses a synchronous IPC on the
// client side.
class FidlTest {
 public:
  explicit FidlTest(MultiProc multiproc) {
    zx_handle_t server = service_ptr_.NewRequest().TakeChannel().release();
    thread_or_process_.Launch("FidlTest::ThreadFunc", &server, 1, multiproc);
  }

  static void ThreadFunc(std::vector<zx_handle_t> handles) {
    FXL_CHECK(handles.size() == 1);
    zx::channel channel(handles[0]);

    async::Loop loop(&kAsyncLoopConfigAttachToThread);
    RoundTripServiceImpl service_impl;
    fidl::Binding<fuchsia::zircon::benchmarks::RoundTripService> binding(
        &service_impl, std::move(channel));
    binding.set_error_handler([&loop](zx_status_t status) { loop.Quit(); });
    loop.Run();
  }

  void Run() {
    uint32_t result;
    FXL_CHECK(service_ptr_->RoundTripTest(123, &result) == ZX_OK);
    FXL_CHECK(result == 456);
  }

 private:
  ThreadOrProcess thread_or_process_;
  fuchsia::zircon::benchmarks::RoundTripServiceSyncPtr service_ptr_;
};

// Test the round trip time for waking up threads using Zircon futexes.
// Note that Zircon does not support cross-process futexes, only
// within-process futexes, so there is no multi-process version of this
// test case.
class FutexTest {
 public:
  FutexTest() {
    thread_ = std::thread([this]() { ThreadFunc(); });
  }

  ~FutexTest() {
    Wake(&futex1_, 2);  // Tell the thread to shut down.
    thread_.join();
  }

  void Run() {
    Wake(&futex1_, 1);
    FXL_CHECK(!Wait(&futex2_));
  }

 private:
  void ThreadFunc() {
    for (;;) {
      if (Wait(&futex1_))
        break;
      Wake(&futex2_, 1);
    }
  }

  void Wake(volatile int* ptr, int wake_value) {
    *ptr = wake_value;
    FXL_CHECK(zx_futex_wake(const_cast<int*>(ptr), 1) == ZX_OK);
  }

  bool Wait(volatile int* ptr) {
    for (;;) {
      int val = *ptr;
      if (val != 0) {
        // We were signaled.  Reset the state to unsignaled.
        *ptr = 0;
        // Return whether we got a request to shut down.
        return val == 2;
      }
      zx_status_t status = zx_futex_wait(const_cast<int*>(ptr), val,
                                         ZX_HANDLE_INVALID, ZX_TIME_INFINITE);
      FXL_CHECK(status == ZX_OK || status == ZX_ERR_BAD_STATE);
    }
  }

  std::thread thread_;
  volatile int futex1_ = 0;  // Signals from client to server.
  volatile int futex2_ = 0;  // Signals from server to client.
};

// Test the round trip time for waking up threads using pthread condition
// variables (condvars).  Condvars are implemented using futexes, so we
// expect this to be a bit slower than FutexTest due to the overhead that
// pthread's condvar implementation adds.
class PthreadCondvarTest {
 public:
  PthreadCondvarTest() {
    FXL_CHECK(pthread_mutex_init(&mutex_, nullptr) == 0);
    FXL_CHECK(pthread_cond_init(&condvar1_, nullptr) == 0);
    FXL_CHECK(pthread_cond_init(&condvar2_, nullptr) == 0);
    thread_ = std::thread([this]() { ThreadFunc(); });
  }

  ~PthreadCondvarTest() {
    // Tell the thread to shut down.
    FXL_CHECK(pthread_mutex_lock(&mutex_) == 0);
    state_ = EXIT;
    FXL_CHECK(pthread_cond_signal(&condvar1_) == 0);
    FXL_CHECK(pthread_mutex_unlock(&mutex_) == 0);

    thread_.join();

    FXL_CHECK(pthread_cond_destroy(&condvar1_) == 0);
    FXL_CHECK(pthread_cond_destroy(&condvar2_) == 0);
    FXL_CHECK(pthread_mutex_destroy(&mutex_) == 0);
  }

  void Run() {
    FXL_CHECK(pthread_mutex_lock(&mutex_) == 0);
    // Wake the child.
    state_ = WAKE_CHILD;
    FXL_CHECK(pthread_cond_signal(&condvar1_) == 0);
    // Wait for the reply.
    while (state_ != REPLY_TO_PARENT)
      FXL_CHECK(pthread_cond_wait(&condvar2_, &mutex_) == 0);
    FXL_CHECK(pthread_mutex_unlock(&mutex_) == 0);
  }

 private:
  void ThreadFunc() {
    FXL_CHECK(pthread_mutex_lock(&mutex_) == 0);
    for (;;) {
      if (state_ == EXIT)
        break;
      if (state_ == WAKE_CHILD) {
        state_ = REPLY_TO_PARENT;
        FXL_CHECK(pthread_cond_signal(&condvar2_) == 0);
      }
      FXL_CHECK(pthread_cond_wait(&condvar1_, &mutex_) == 0);
    }
    FXL_CHECK(pthread_mutex_unlock(&mutex_) == 0);
  }

  std::thread thread_;
  pthread_mutex_t mutex_;
  pthread_cond_t condvar1_;  // Signals from parent to child.
  pthread_cond_t condvar2_;  // Signals from child to parent.
  enum { INITIAL, WAKE_CHILD, REPLY_TO_PARENT, EXIT } state_ = INITIAL;
};

struct ThreadFuncEntry {
  const char* name;
  ThreadFunc func;
};

// clang-format off
const ThreadFuncEntry thread_funcs[] = {
#define DEF_FUNC(FUNC) { #FUNC, FUNC },
  DEF_FUNC(BasicChannelTest::ThreadFunc)
  DEF_FUNC(ChannelPortTest::ThreadFunc)
  DEF_FUNC(ChannelCallTest::ThreadFunc)
  DEF_FUNC(PortTest::ThreadFunc)
  DEF_FUNC(EventPortTest::ThreadFunc)
  DEF_FUNC(SocketPortTest::ThreadFunc)
  DEF_FUNC(FidlTest::ThreadFunc)
#undef DEF_FUNC
};
// clang-format on

ThreadFunc GetThreadFunc(const char* name) {
  for (size_t i = 0; i < arraysize(thread_funcs); ++i) {
    if (!strcmp(name, thread_funcs[i].name))
      return thread_funcs[i].func;
  }
  FXL_LOG(FATAL) << "Thread function not found: " << name;
  return nullptr;
}

// Register a test that has two variants, single-process and multi-process.
template <class TestClass, typename... Args>
void RegisterTestMultiProc(const char* base_name, Args... args) {
  fbenchmark::RegisterTest<TestClass>(
      (std::string(base_name) + "_SingleProcess").c_str(), SingleProcess,
      std::forward<Args>(args)...);
  fbenchmark::RegisterTest<TestClass>(
      (std::string(base_name) + "_MultiProcess").c_str(), MultiProcess,
      std::forward<Args>(args)...);
}

__attribute__((constructor)) void RegisterTests() {
  RegisterTestMultiProc<BasicChannelTest>("RoundTrip_BasicChannel",
                                          /* count= */ 1, /* size= */ 4);
  RegisterTestMultiProc<BasicChannelTest>(
      "IpcThroughput_BasicChannel_1_64kbytes",
      /* msg_count= */ 1, /* msg_size= */ 64 * 1024);

  // These next two benchmarks allocate and free a significant amount of
  // memory so their performance can be heavily dependent on kernel allocator
  // performance.
  RegisterTestMultiProc<BasicChannelTest>(
      "IpcThroughput_BasicChannel_1024_4bytes",
      /* msg_count= */ 1024, /* msg_size= */ 4);
  RegisterTestMultiProc<BasicChannelTest>(
      "IpcThroughput_BasicChannel_1024_64kbytes",
      /* msg_count= */ 1024, /* msg_size= */ 64 * 1024);

  RegisterTestMultiProc<ChannelPortTest>("RoundTrip_ChannelPort");
  RegisterTestMultiProc<ChannelCallTest>("RoundTrip_ChannelCall");
  RegisterTestMultiProc<PortTest>("RoundTrip_Port");
  RegisterTestMultiProc<EventPortTest>("RoundTrip_EventPort");
  RegisterTestMultiProc<SocketPortTest>("RoundTrip_SocketPort");
  RegisterTestMultiProc<FidlTest>("RoundTrip_Fidl");
  fbenchmark::RegisterTest<FutexTest>("RoundTrip_Futex_SingleProcess");
  fbenchmark::RegisterTest<PthreadCondvarTest>(
      "RoundTrip_PthreadCondvar_SingleProcess");
}

}  // namespace

void RunSubprocess(const char* func_name) {
  auto func = GetThreadFunc(func_name);
  // Retrieve the handles.
  std::vector<zx_handle_t> handles;
  for (;;) {
    zx_handle_t handle =
        zx_take_startup_handle(PA_HND(PA_USER0, handles.size()));
    if (handle == ZX_HANDLE_INVALID)
      break;
    handles.push_back(handle);
  }
  func(handles);
}
