/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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.
 */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <string>

#include <android-base/file.h>

#include <benchmark/benchmark.h>

#include <backtrace/Backtrace.h>
#include <backtrace/BacktraceMap.h>
#include <unwindstack/Memory.h>

// Definitions of prctl arguments to set a vma name in Android kernels.
#define ANDROID_PR_SET_VMA 0x53564d41
#define ANDROID_PR_SET_VMA_ANON_NAME 0

constexpr size_t kNumMaps = 2000;

static bool CountMaps(pid_t pid, size_t* num_maps) {
  // Minimize the calls that might allocate memory. If too much memory
  // gets allocated, then this routine will add extra maps and the next
  // call will fail to get the same number of maps as before.
  int fd =
      open((std::string("/proc/") + std::to_string(pid) + "/maps").c_str(), O_RDONLY | O_CLOEXEC);
  if (fd == -1) {
    fprintf(stderr, "Cannot open map file for pid %d: %s\n", pid, strerror(errno));
    return false;
  }
  *num_maps = 0;
  while (true) {
    char buffer[2048];
    ssize_t bytes = read(fd, buffer, sizeof(buffer));
    if (bytes <= 0) {
      break;
    }
    // Count the '\n'.
    for (size_t i = 0; i < static_cast<size_t>(bytes); i++) {
      if (buffer[i] == '\n') {
        ++*num_maps;
      }
    }
  }

  close(fd);
  return true;
}

static void CreateMap(benchmark::State& state, BacktraceMap* (*map_func)(pid_t, bool)) {
  // Create a remote process so that the map data is exactly the same.
  // Also, so that we can create a set number of maps.
  pid_t pid;
  if ((pid = fork()) == 0) {
    size_t num_maps;
    if (!CountMaps(getpid(), &num_maps)) {
      exit(1);
    }
    // Create uniquely named maps.
    std::vector<void*> maps;
    for (size_t i = num_maps; i < kNumMaps; i++) {
      int flags = PROT_READ | PROT_WRITE;
      // Alternate page type to make sure a map entry is added for each call.
      if ((i % 2) == 0) {
        flags |= PROT_EXEC;
      }
      void* memory = mmap(nullptr, PAGE_SIZE, flags, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
      if (memory == MAP_FAILED) {
        fprintf(stderr, "Failed to create map: %s\n", strerror(errno));
        exit(1);
      }
      memset(memory, 0x1, PAGE_SIZE);
      if (prctl(ANDROID_PR_SET_VMA, ANDROID_PR_SET_VMA_ANON_NAME, memory, PAGE_SIZE, "test_map") ==
          -1) {
        fprintf(stderr, "Failed: %s\n", strerror(errno));
      }
      maps.push_back(memory);
    }

    if (!CountMaps(getpid(), &num_maps)) {
      exit(1);
    }

    if (num_maps < kNumMaps) {
      fprintf(stderr, "Maps set incorrectly: %zu found, %zu expected at least.\n", num_maps,
              kNumMaps);
      std::string str;
      android::base::ReadFileToString("/proc/self/maps", &str);
      fprintf(stderr, "%s\n", str.c_str());
      exit(1);
    }

    // Wait for an hour at most.
    sleep(3600);
    exit(1);
  } else if (pid < 0) {
    fprintf(stderr, "Fork failed: %s\n", strerror(errno));
    return;
  }

  size_t num_maps = 0;
  for (size_t i = 0; i < 2000; i++) {
    if (CountMaps(pid, &num_maps) && num_maps >= kNumMaps) {
      break;
    }
    usleep(1000);
  }
  if (num_maps < kNumMaps) {
    fprintf(stderr, "Timed out waiting for the number of maps available: %zu\n", num_maps);
    return;
  }

  while (state.KeepRunning()) {
    BacktraceMap* map = map_func(pid, false);
    if (map == nullptr) {
      fprintf(stderr, "Failed to create map\n");
      return;
    }
    delete map;
  }

  kill(pid, SIGKILL);
  waitpid(pid, nullptr, 0);
}

static void BM_create_map(benchmark::State& state) {
  CreateMap(state, BacktraceMap::Create);
}
BENCHMARK(BM_create_map);

using BacktraceCreateFn = decltype(Backtrace::Create);

static void CreateBacktrace(benchmark::State& state, BacktraceMap* map, BacktraceCreateFn fn) {
  while (state.KeepRunning()) {
    std::unique_ptr<Backtrace> backtrace(fn(getpid(), gettid(), map));
    backtrace->Unwind(0);
  }
}

static void BM_create_backtrace(benchmark::State& state) {
  std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(getpid()));
  CreateBacktrace(state, backtrace_map.get(), Backtrace::Create);
}
BENCHMARK(BM_create_backtrace);

BENCHMARK_MAIN();
