diff --git a/src/backend/A64/perf_map.cpp b/src/backend/A64/perf_map.cpp new file mode 100644 index 00000000..af46fa08 --- /dev/null +++ b/src/backend/A64/perf_map.cpp @@ -0,0 +1,89 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2018 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#include +#include + +#ifdef __linux__ + +#include +#include +#include +#include +#include + +#include + +#include "common/common_types.h" + +namespace Dynarmic::BackendA64 { + +namespace { +std::mutex mutex; +std::FILE* file = nullptr; + +void OpenFile() { + const char* perf_dir = std::getenv("PERF_BUILDID_DIR"); + if (!perf_dir) { + file = nullptr; + return; + } + + const pid_t pid = getpid(); + const std::string filename = fmt::format("{:s}/perf-{:d}.map", perf_dir, pid); + + file = std::fopen(filename.c_str(), "w"); + if (!file) { + return; + } + + std::setvbuf(file, nullptr, _IONBF, 0); +} +} // anonymous namespace + +namespace detail { +void PerfMapRegister(const void* start, const void* end, const std::string& friendly_name) { + std::lock_guard guard{mutex}; + + if (!file) { + OpenFile(); + if (!file) { + return; + } + } + + const std::string line = fmt::format("{:016x} {:016x} {:s}\n", reinterpret_cast(start), reinterpret_cast(end) - reinterpret_cast(start), friendly_name); + std::fwrite(line.data(), sizeof *line.data(), line.size(), file); +} +} // namespace detail + +void PerfMapClear() { + std::lock_guard guard{mutex}; + + if (!file) { + return; + } + + std::fclose(file); + file = nullptr; + OpenFile(); +} + +} // namespace Dynarmic::BackendX64 + +#else + +namespace Dynarmic::BackendA64 { + +namespace detail { +void PerfMapRegister(const void*, const void*, const std::string&) {} +} // namespace detail + +void PerfMapClear() {} + +} // namespace Dynarmic::BackendX64 + +#endif diff --git a/src/backend/A64/perf_map.h b/src/backend/A64/perf_map.h new file mode 100644 index 00000000..0b563dd1 --- /dev/null +++ b/src/backend/A64/perf_map.h @@ -0,0 +1,27 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2018 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#pragma once + +#include +#include + +#include "common/cast_util.h" + +namespace Dynarmic::BackendA64 { + +namespace detail { +void PerfMapRegister(const void* start, const void* end, const std::string& friendly_name); +} // namespace detail + +template +void PerfMapRegister(T start, const void* end, const std::string& friendly_name) { + detail::PerfMapRegister(Common::BitCast(start), end, friendly_name); +} + +void PerfMapClear(); + +} // namespace Dynarmic::BackendX64