// 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 <lib/fdio/spawn.h>
#include <lib/zx/handle.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <lib/zx/time.h>
#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

#include <perftest/perftest.h>

#include "assert.h"

namespace {

constexpr const char* kPath = "/pkg/bin/context_switch_overhead_helper";

void ChannelWait(const zx::channel& channel) {
  // If we only pass ZX_CHANNEL_READABLE here, we will end up waiting
  // forever if the process holding the other channel endpoint dies, so we
  // should pass ZX_CHANNEL_PEER_CLOSED too.
  ASSERT_OK(channel.wait_one(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, zx::time::infinite(),
                             nullptr));
}

// Measure the time taken for NUM_CPUS pairs of threads, running in parallel, to each start up and
// then execute |number_of_switches| round trips (via eventpair wakeup), when running in a separate
// process. Each pair of threads is pinned to a different CPU on the system.
//
// The flow is as follows:
// Host = this process
// Helper = The helper process runnning the tests.
//
// 1. Helper sends a small message over the channel, to signal it is ready to run a test.
// 2. Host sends a message containing the number of context switches to do.
// 3. Helper sends a small message to signal the setup is ready.
// 4. Helper runs the test, sending another small message to signal the test is done.
// 5. Helper waits for another message and returns to step 2.
//
// The test is intended to reach peak context switches on all cores, and it is meant to be sensitive
// to changes that modify shared data on cache-lines between cores.
bool ContextSwitchTest(perftest::RepeatState* state, size_t number_of_switches) {
  zx::channel chan1, chan2;
  ASSERT_OK(zx::channel::create(0, &chan1, &chan2));

  const char* const argv[] = {kPath, nullptr};

  zx::job job;
  ASSERT_OK(zx::job::create(*zx::job::default_job(), 0, &job));
  zx::handle process;
  fdio_spawn_action_t actions[] = {
      {
          .action = FDIO_SPAWN_ACTION_ADD_HANDLE,
          .h =
              {
                  .id = PA_USER0,
                  .handle = chan2.release(),
              },
      },
  };
  char err_msg_out[FDIO_SPAWN_ERR_MSG_MAX_LENGTH] = {};
  if (zx_status_t status =
          fdio_spawn_etc(job.get(), FDIO_SPAWN_CLONE_ALL, kPath, argv, nullptr /* environ */,
                         std::size(actions), actions, process.reset_and_get_address(), err_msg_out);
      status != ZX_OK) {
    ZX_PANIC("fdio_spawn_etc(): %s; %s", zx_status_get_string(status), err_msg_out);
  }

  char out[1024];
  uint32_t len;

  ChannelWait(chan1);
  ASSERT_OK(chan1.read(0, &out, nullptr, sizeof(out), 0, &len, nullptr));

  state->DeclareStep("setup");
  state->DeclareStep("execute");

  while (state->KeepRunning()) {
    ASSERT_OK(chan1.write(0, &number_of_switches, sizeof(number_of_switches), nullptr, 0));
    ChannelWait(chan1);
    ASSERT_OK(chan1.read(0, &out, nullptr, sizeof(out), 0, &len, nullptr));
    state->NextStep();
    ChannelWait(chan1);
    ASSERT_OK(chan1.read(0, &out, nullptr, sizeof(out), 0, &len, nullptr));
  }

  ASSERT_OK(job.kill());
  ASSERT_OK(process.wait_one(ZX_TASK_TERMINATED, zx::time::infinite(), nullptr));

  return true;
}

void RegisterTests() { perftest::RegisterTest("ContextSwitch/1000", ContextSwitchTest, 1000); }
PERFTEST_CTOR(RegisterTests)

}  // namespace
