//
//
// Copyright 2017 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//

// Test various closure related operations

#include <sstream>

#include <benchmark/benchmark.h>

#include <grpc/grpc.h>

#include "src/core/lib/gpr/spinlock.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/core/util/test_config.h"
#include "test/cpp/microbenchmarks/helpers.h"
#include "test/cpp/util/test_config.h"

static void BM_NoOpExecCtx(benchmark::State& state) {
  for (auto _ : state) {
    grpc_core::ExecCtx exec_ctx;
  }
}
BENCHMARK(BM_NoOpExecCtx);

static void BM_WellFlushed(benchmark::State& state) {
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    grpc_core::ExecCtx::Get()->Flush();
  }
}
BENCHMARK(BM_WellFlushed);

static void DoNothing(void* /*arg*/, grpc_error_handle /*error*/) {}

static void BM_ClosureInitAgainstExecCtx(benchmark::State& state) {
  grpc_closure c;
  for (auto _ : state) {
    benchmark::DoNotOptimize(
        GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, grpc_schedule_on_exec_ctx));
  }
}
BENCHMARK(BM_ClosureInitAgainstExecCtx);

static void BM_ClosureInitAgainstCombiner(benchmark::State& state) {
  grpc_core::Combiner* combiner = grpc_combiner_create(
      grpc_event_engine::experimental::CreateEventEngine());
  grpc_closure c;
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    benchmark::DoNotOptimize(
        GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, nullptr));
  }
  GRPC_COMBINER_UNREF(combiner, "finished");
}
BENCHMARK(BM_ClosureInitAgainstCombiner);

static void BM_ClosureRun(benchmark::State& state) {
  grpc_closure c;
  GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    grpc_core::Closure::Run(DEBUG_LOCATION, &c, absl::OkStatus());
  }
}
BENCHMARK(BM_ClosureRun);

static void BM_ClosureCreateAndRun(benchmark::State& state) {
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    grpc_core::Closure::Run(
        DEBUG_LOCATION,
        GRPC_CLOSURE_CREATE(DoNothing, nullptr, grpc_schedule_on_exec_ctx),
        absl::OkStatus());
  }
}
BENCHMARK(BM_ClosureCreateAndRun);

static void BM_ClosureInitAndRun(benchmark::State& state) {
  grpc_core::ExecCtx exec_ctx;
  grpc_closure c;
  for (auto _ : state) {
    grpc_core::Closure::Run(
        DEBUG_LOCATION,
        GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, grpc_schedule_on_exec_ctx),
        absl::OkStatus());
  }
}
BENCHMARK(BM_ClosureInitAndRun);

static void BM_ClosureSchedOnExecCtx(benchmark::State& state) {
  grpc_closure c;
  GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c, absl::OkStatus());
    grpc_core::ExecCtx::Get()->Flush();
  }
}
BENCHMARK(BM_ClosureSchedOnExecCtx);

static void BM_ClosureSched2OnExecCtx(benchmark::State& state) {
  grpc_closure c1;
  grpc_closure c2;
  GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
  GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c1, absl::OkStatus());
    grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c2, absl::OkStatus());
    grpc_core::ExecCtx::Get()->Flush();
  }
}
BENCHMARK(BM_ClosureSched2OnExecCtx);

static void BM_ClosureSched3OnExecCtx(benchmark::State& state) {
  grpc_closure c1;
  grpc_closure c2;
  grpc_closure c3;
  GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
  GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
  GRPC_CLOSURE_INIT(&c3, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c1, absl::OkStatus());
    grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c2, absl::OkStatus());
    grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c3, absl::OkStatus());
    grpc_core::ExecCtx::Get()->Flush();
  }
}
BENCHMARK(BM_ClosureSched3OnExecCtx);

static void BM_AcquireMutex(benchmark::State& state) {
  // for comparison with the combiner stuff below
  gpr_mu mu;
  gpr_mu_init(&mu);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    gpr_mu_lock(&mu);
    DoNothing(nullptr, absl::OkStatus());
    gpr_mu_unlock(&mu);
  }
  gpr_mu_destroy(&mu);
}
BENCHMARK(BM_AcquireMutex);

static void BM_TryAcquireMutex(benchmark::State& state) {
  // for comparison with the combiner stuff below
  gpr_mu mu;
  gpr_mu_init(&mu);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    if (gpr_mu_trylock(&mu)) {
      DoNothing(nullptr, absl::OkStatus());
      gpr_mu_unlock(&mu);
    } else {
      abort();
    }
  }
  gpr_mu_destroy(&mu);
}
BENCHMARK(BM_TryAcquireMutex);

static void BM_AcquireSpinlock(benchmark::State& state) {
  // for comparison with the combiner stuff below
  gpr_spinlock mu = GPR_SPINLOCK_INITIALIZER;
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    gpr_spinlock_lock(&mu);
    DoNothing(nullptr, absl::OkStatus());
    gpr_spinlock_unlock(&mu);
  }
}
BENCHMARK(BM_AcquireSpinlock);

static void BM_TryAcquireSpinlock(benchmark::State& state) {
  // for comparison with the combiner stuff below
  gpr_spinlock mu = GPR_SPINLOCK_INITIALIZER;
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    if (gpr_spinlock_trylock(&mu)) {
      DoNothing(nullptr, absl::OkStatus());
      gpr_spinlock_unlock(&mu);
    } else {
      abort();
    }
  }
}
BENCHMARK(BM_TryAcquireSpinlock);

static void BM_ClosureSchedOnCombiner(benchmark::State& state) {
  grpc_core::Combiner* combiner = grpc_combiner_create(
      grpc_event_engine::experimental::CreateEventEngine());
  grpc_closure c;
  GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, nullptr);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    combiner->Run(&c, absl::OkStatus());
    grpc_core::ExecCtx::Get()->Flush();
  }
  GRPC_COMBINER_UNREF(combiner, "finished");
}
BENCHMARK(BM_ClosureSchedOnCombiner);

static void BM_ClosureSched2OnCombiner(benchmark::State& state) {
  grpc_core::Combiner* combiner = grpc_combiner_create(
      grpc_event_engine::experimental::CreateEventEngine());
  grpc_closure c1;
  grpc_closure c2;
  GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, nullptr);
  GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, nullptr);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    combiner->Run(&c1, absl::OkStatus());
    combiner->Run(&c2, absl::OkStatus());
    grpc_core::ExecCtx::Get()->Flush();
  }
  GRPC_COMBINER_UNREF(combiner, "finished");
}
BENCHMARK(BM_ClosureSched2OnCombiner);

static void BM_ClosureSched3OnCombiner(benchmark::State& state) {
  grpc_core::Combiner* combiner = grpc_combiner_create(
      grpc_event_engine::experimental::CreateEventEngine());
  grpc_closure c1;
  grpc_closure c2;
  grpc_closure c3;
  GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, nullptr);
  GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, nullptr);
  GRPC_CLOSURE_INIT(&c3, DoNothing, nullptr, nullptr);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    combiner->Run(&c1, absl::OkStatus());
    combiner->Run(&c2, absl::OkStatus());
    combiner->Run(&c3, absl::OkStatus());
    grpc_core::ExecCtx::Get()->Flush();
  }
  GRPC_COMBINER_UNREF(combiner, "finished");
}
BENCHMARK(BM_ClosureSched3OnCombiner);

static void BM_ClosureSched2OnTwoCombiners(benchmark::State& state) {
  std::shared_ptr<grpc_event_engine::experimental::EventEngine> engine =
      grpc_event_engine::experimental::CreateEventEngine();
  grpc_core::Combiner* combiner1 = grpc_combiner_create(engine);
  grpc_core::Combiner* combiner2 = grpc_combiner_create(engine);
  grpc_closure c1;
  grpc_closure c2;
  GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, nullptr);
  GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, nullptr);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    combiner1->Run(&c1, absl::OkStatus());
    combiner2->Run(&c2, absl::OkStatus());
    grpc_core::ExecCtx::Get()->Flush();
  }
  GRPC_COMBINER_UNREF(combiner1, "finished");
  GRPC_COMBINER_UNREF(combiner2, "finished");
}
BENCHMARK(BM_ClosureSched2OnTwoCombiners);

static void BM_ClosureSched4OnTwoCombiners(benchmark::State& state) {
  std::shared_ptr<grpc_event_engine::experimental::EventEngine> engine =
      grpc_event_engine::experimental::CreateEventEngine();
  grpc_core::Combiner* combiner1 = grpc_combiner_create(engine);
  grpc_core::Combiner* combiner2 = grpc_combiner_create(engine);
  grpc_closure c1;
  grpc_closure c2;
  grpc_closure c3;
  grpc_closure c4;
  GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, nullptr);
  GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, nullptr);
  GRPC_CLOSURE_INIT(&c3, DoNothing, nullptr, nullptr);
  GRPC_CLOSURE_INIT(&c4, DoNothing, nullptr, nullptr);
  grpc_core::ExecCtx exec_ctx;
  for (auto _ : state) {
    combiner1->Run(&c1, absl::OkStatus());
    combiner2->Run(&c2, absl::OkStatus());
    combiner1->Run(&c3, absl::OkStatus());
    combiner2->Run(&c4, absl::OkStatus());
    grpc_core::ExecCtx::Get()->Flush();
  }
  GRPC_COMBINER_UNREF(combiner1, "finished");
  GRPC_COMBINER_UNREF(combiner2, "finished");
}
BENCHMARK(BM_ClosureSched4OnTwoCombiners);

// Helper that continuously reschedules the same closure against something until
// the benchmark is complete
class Rescheduler {
 public:
  explicit Rescheduler(benchmark::State& state) : state_(state) {
    GRPC_CLOSURE_INIT(&closure_, Step, this, nullptr);
  }

  void ScheduleFirst() {
    grpc_core::ExecCtx::Run(DEBUG_LOCATION, &closure_, absl::OkStatus());
  }

  void ScheduleFirstAgainstDifferentScheduler() {
    grpc_core::ExecCtx::Run(DEBUG_LOCATION,
                            GRPC_CLOSURE_CREATE(Step, this, nullptr),
                            absl::OkStatus());
  }

 private:
  benchmark::State& state_;
  grpc_closure closure_;

  static void Step(void* arg, grpc_error_handle /*error*/) {
    Rescheduler* self = static_cast<Rescheduler*>(arg);
    if (self->state_.KeepRunning()) {
      grpc_core::ExecCtx::Run(DEBUG_LOCATION, &self->closure_,
                              absl::OkStatus());
    }
  }
};

static void BM_ClosureReschedOnExecCtx(benchmark::State& state) {
  grpc_core::ExecCtx exec_ctx;
  Rescheduler r(state);
  r.ScheduleFirst();
  grpc_core::ExecCtx::Get()->Flush();
}
BENCHMARK(BM_ClosureReschedOnExecCtx);

// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
// and others do not. This allows us to support both modes.
namespace benchmark {
void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
}  // namespace benchmark

int main(int argc, char** argv) {
  grpc::testing::TestEnvironment env(&argc, argv);
  LibraryInitializer libInit;
  ::benchmark::Initialize(&argc, argv);
  grpc::testing::InitTest(&argc, &argv, false);
  benchmark::RunTheBenchmarksNamespaced();
  return 0;
}
