/*
 * Copyright (C) 2015 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.
 */

#ifndef SIMPLE_PERF_ENVIRONMENT_H_
#define SIMPLE_PERF_ENVIRONMENT_H_

#include <sys/types.h>
#include <time.h>

#include <functional>
#include <set>
#include <string>
#include <vector>

#include "build_id.h"

std::vector<int> GetOnlineCpus();
std::vector<int> GetCpusFromString(const std::string& s);

struct KernelMmap {
  std::string name;
  uint64_t start_addr;
  uint64_t len;
  std::string filepath;
};

void GetKernelAndModuleMmaps(KernelMmap* kernel_mmap, std::vector<KernelMmap>* module_mmaps);

struct ThreadComm {
  pid_t pid, tid;
  std::string comm;
};

bool GetThreadComms(std::vector<ThreadComm>* thread_comms);
bool GetProcessIdForThread(pid_t tid, pid_t* pid);

struct ThreadMmap {
  uint64_t start_addr;
  uint64_t len;
  uint64_t pgoff;
  std::string name;
  bool executable;
};

bool GetThreadMmapsInProcess(pid_t pid, std::vector<ThreadMmap>* thread_mmaps);

constexpr char DEFAULT_KERNEL_FILENAME_FOR_BUILD_ID[] = "[kernel.kallsyms]";

bool GetKernelBuildId(BuildId* build_id);
bool GetModuleBuildId(const std::string& module_name, BuildId* build_id);

std::vector<pid_t> GetThreadsInProcess(pid_t pid);
bool GetValidThreadsFromThreadString(const std::string& tid_str, std::set<pid_t>* tid_set);

bool CheckPerfEventLimit();
bool CheckSampleFrequency(uint64_t sample_freq);
bool CheckKernelSymbolAddresses();

#if defined(__linux__)
static inline uint64_t GetSystemClock() {
  timespec ts;
  // Assume clock_gettime() doesn't fail.
  clock_gettime(CLOCK_MONOTONIC, &ts);
  return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
}
#endif

#endif  // SIMPLE_PERF_ENVIRONMENT_H_
