//===-- Timer.cpp ---------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/Stream.h"

#include <algorithm>
#include <map>
#include <mutex>
#include <utility>
#include <vector>

#include <assert.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>

using namespace lldb_private;

#define TIMER_INDENT_AMOUNT 2

namespace {
typedef std::vector<Timer *> TimerStack;
static std::atomic<Timer::Category *> g_categories;
} // end of anonymous namespace

std::atomic<bool> Timer::g_quiet(true);
std::atomic<unsigned> Timer::g_display_depth(0);
static std::mutex &GetFileMutex() {
  static std::mutex *g_file_mutex_ptr = new std::mutex();
  return *g_file_mutex_ptr;
}

static TimerStack &GetTimerStackForCurrentThread() {
  static thread_local TimerStack g_stack;
  return g_stack;
}

Timer::Category::Category(const char *cat) : m_name(cat) {
  m_nanos.store(0, std::memory_order_release);
  m_nanos_total.store(0, std::memory_order_release);
  m_count.store(0, std::memory_order_release);
  Category *expected = g_categories;
  do {
    m_next = expected;
  } while (!g_categories.compare_exchange_weak(expected, this));
}

void Timer::SetQuiet(bool value) { g_quiet = value; }

Timer::Timer(Timer::Category &category, const char *format, ...)
    : m_category(category), m_total_start(std::chrono::steady_clock::now()) {
  TimerStack &stack = GetTimerStackForCurrentThread();

  stack.push_back(this);
  if (g_quiet && stack.size() <= g_display_depth) {
    std::lock_guard<std::mutex> lock(GetFileMutex());

    // Indent
    ::fprintf(stdout, "%*s", int(stack.size() - 1) * TIMER_INDENT_AMOUNT, "");
    // Print formatted string
    va_list args;
    va_start(args, format);
    ::vfprintf(stdout, format, args);
    va_end(args);

    // Newline
    ::fprintf(stdout, "\n");
  }
}

Timer::~Timer() {
  using namespace std::chrono;

  auto stop_time = steady_clock::now();
  auto total_dur = stop_time - m_total_start;
  auto timer_dur = total_dur - m_child_duration;

  TimerStack &stack = GetTimerStackForCurrentThread();
  if (g_quiet && stack.size() <= g_display_depth) {
    std::lock_guard<std::mutex> lock(GetFileMutex());
    ::fprintf(stdout, "%*s%.9f sec (%.9f sec)\n",
              int(stack.size() - 1) * TIMER_INDENT_AMOUNT, "",
              duration<double>(total_dur).count(),
              duration<double>(timer_dur).count());
  }

  assert(stack.back() == this);
  stack.pop_back();
  if (!stack.empty())
    stack.back()->ChildDuration(total_dur);

  // Keep total results for each category so we can dump results.
  m_category.m_nanos += std::chrono::nanoseconds(timer_dur).count();
  m_category.m_nanos_total += std::chrono::nanoseconds(total_dur).count();
  m_category.m_count++;
}

void Timer::SetDisplayDepth(uint32_t depth) { g_display_depth = depth; }

/* binary function predicate:
 * - returns whether a person is less than another person
 */
namespace {
struct Stats {
  const char *name;
  uint64_t nanos;
  uint64_t nanos_total;
  uint64_t count;
};
} // namespace

static bool CategoryMapIteratorSortCriterion(const Stats &lhs,
                                             const Stats &rhs) {
  return lhs.nanos > rhs.nanos;
}

void Timer::ResetCategoryTimes() {
  for (Category *i = g_categories; i; i = i->m_next) {
    i->m_nanos.store(0, std::memory_order_release);
    i->m_nanos_total.store(0, std::memory_order_release);
    i->m_count.store(0, std::memory_order_release);
  }
}

void Timer::DumpCategoryTimes(Stream *s) {
  std::vector<Stats> sorted;
  for (Category *i = g_categories; i; i = i->m_next) {
    uint64_t nanos = i->m_nanos.load(std::memory_order_acquire);
    if (nanos) {
      uint64_t nanos_total = i->m_nanos_total.load(std::memory_order_acquire);
      uint64_t count = i->m_count.load(std::memory_order_acquire);
      Stats stats{i->m_name, nanos, nanos_total, count};
      sorted.push_back(stats);
    }
  }
  if (sorted.empty())
    return; // Later code will break without any elements.

  // Sort by time
  llvm::sort(sorted.begin(), sorted.end(), CategoryMapIteratorSortCriterion);

  for (const auto &stats : sorted)
    s->Printf("%.9f sec (total: %.3fs; child: %.3fs; count: %" PRIu64
              ") for %s\n",
              stats.nanos / 1000000000., stats.nanos_total / 1000000000.,
              (stats.nanos_total - stats.nanos) / 1000000000., stats.count,
              stats.name);
}
