Remove some files that weren't even staged :|

This commit is contained in:
Dr. Chat 2018-05-07 19:05:29 -05:00
parent 212688249c
commit e0cef9dcd6
3 changed files with 0 additions and 291 deletions

View File

@ -1,150 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/debug/profiler.h"
#include "xenia/base/mutex.h"
#include "xenia/cpu/backend/code_cache.h"
#include "xenia/cpu/ppc/ppc_opcode_info.h"
#include "xenia/cpu/stack_walker.h"
#include "xenia/debug/debugger.h"
#include "xenia/kernel/xthread.h"
#include "xenia/emulator.h"
// Credits go to Very Sleepy for the general design
// https://github.com/VerySleepy/verysleepy
namespace xe {
namespace debug {
Profiler::Profiler(Debugger* debugger) : debugger_(debugger) {}
void Profiler::Start() {
assert_false(is_profiling_);
total_samples_collected_.exchange(0);
is_profiling_ = true;
timer_.Start();
auto params = threading::Thread::CreationParameters();
worker_thread_ = xe::threading::Thread::Create(
params, std::bind(&Profiler::ProfilerEntry, this));
}
void Profiler::Stop() {
assert_true(is_profiling_);
is_profiling_ = false;
timer_.Stop();
profiling_stop_fence_.Wait();
worker_thread_.reset();
CalculateSamplesPerInstruction();
}
void Profiler::OnThreadsChanged() {
auto lock = global_critical_region::AcquireDirect();
should_refresh_threads_ = true;
}
void Profiler::CalculateSamplesPerInstruction() {
auto cache = debugger_->emulator()->processor()->backend()->code_cache();
auto memory = debugger_->emulator()->memory();
for (auto& sample : samples_) {
// Translate x86 address to ppc address
auto host_addr = sample.first.second.host_frames[0];
auto func = cache->LookupFunction(host_addr);
if (!func) {
continue;
}
uint32_t ppc_addr = func->MapMachineCodeToGuestAddress(host_addr);
auto code = xe::load_and_swap<uint32_t>(memory->TranslateVirtual(ppc_addr));
auto& disasm = cpu::ppc::GetOpcodeDisasmInfo(cpu::ppc::LookupOpcode(code));
samples_per_instruction_[disasm.name] += sample.second;
}
}
void Profiler::CalculateSamplesPerFunction() {
auto cache = debugger_->emulator()->processor()->backend()->code_cache();
auto memory = debugger_->emulator()->memory();
for (auto& sample : samples_) {
// Translate x86 address to ppc address
auto host_addr = sample.first.second.host_frames[0];
auto func = cache->LookupFunction(host_addr);
if (!func) {
continue;
}
samples_per_function_[func] += sample.second;
}
}
void Profiler::ProfilerEntry() {
threading::Thread::GetCurrentThread()->set_name("Profiler Thread");
std::vector<threading::Thread*> thread_list;
// Fetch a list of threads from the debugger.
should_refresh_threads_ = true;
// Called when we should profile.
while (is_profiling_) {
if (should_refresh_threads_) {
auto lock = global_critical_region::AcquireDirect();
auto exec_infos = debugger_->QueryThreadExecutionInfos();
for (auto info : exec_infos) {
if (info->thread && !info->thread->is_host_object()) {
thread_list.push_back(info->thread->thread());
}
}
should_refresh_threads_ = false;
}
// Reshuffle the thread list so we don't starve threads. Probably don't need
// to do this every run.
std::random_shuffle(thread_list.begin(), thread_list.end());
for (size_t i = 0; i < thread_list.size(); i++) {
// FIXME: This is totally a race condition. We can't take the global lock
// though, because that would screw with profiling.
if (should_refresh_threads_) {
break;
}
SampleThread(thread_list[i]);
}
}
profiling_stop_fence_.Signal();
}
void Profiler::SampleThread(threading::Thread* thread) {
auto stack_walker = debugger_->emulator()->processor()->stack_walker();
thread->Suspend();
CallStack stack;
stack.depth = stack_walker->CaptureStackTrace(
thread->native_handle(), stack.host_frames, 0,
xe::countof(stack.host_frames), nullptr, nullptr);
assert_true(stack.depth > 0);
thread->Resume();
// Discard the sample if a stack trace could not be captured.
if (stack.depth > 0) {
samples_[{thread->system_id(), stack}]++;
total_samples_[thread->system_id()]++;
total_samples_collected_.fetch_add(1);
}
}
} // namespace debug
} // namespace xe

View File

@ -1,112 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_DEBUG_PROFILER_H_
#define XENIA_DEBUG_PROFILER_H_
#include <cstdint>
#include <map>
#include "xenia/base/assert.h"
#include "xenia/base/clock.h"
#include "xenia/base/threading.h"
namespace xe {
namespace kernel {
class XThread;
}
namespace cpu {
class Function;
}
namespace debug {
class Debugger;
class Profiler {
public:
Profiler(Debugger* debugger);
// Time elapsed between profiling start and stop (or now)
uint64_t GetTicksElapsed() { return timer_.GetTicksElapsed(); }
double GetSecondsElapsed() { return timer_.GetSecondsElapsed(); }
void Start();
void Stop();
// Internal - do not use.
void OnThreadsChanged();
struct CallStack {
uint64_t host_frames[128];
size_t depth;
bool operator<(const CallStack& other) const {
if (depth != other.depth) {
return depth < other.depth;
}
for (size_t i = 0; i < depth; i++) {
if (host_frames[i] != other.host_frames[i]) {
return host_frames[i] < other.host_frames[i];
}
}
return false;
}
};
bool is_profiling() const { return is_profiling_; }
std::map<std::pair<uint64_t, CallStack>, uint64_t>& GetSamplesPerThread() {
assert_false(is_profiling_);
return samples_;
}
std::map<uint64_t, uint64_t>& GetTotalSamplesPerThread() {
assert_false(is_profiling_);
return total_samples_;
}
std::map<const char*, uint64_t>& GetSamplesPerInstruction() {
assert_false(is_profiling_);
return samples_per_instruction_;
}
uint64_t total_samples_collected() { return total_samples_collected_.load(); }
private:
void CalculateSamplesPerInstruction();
void CalculateSamplesPerFunction();
void ProfilerEntry();
void SampleThread(threading::Thread* thread);
Debugger* debugger_ = nullptr;
// TODO: Callstack map
// Map of {thread_id, stack} => # hits
std::map<std::pair<uint64_t, CallStack>, uint64_t> samples_;
std::map<uint64_t, uint64_t> total_samples_; // thread_id => total samples
std::atomic<uint64_t> total_samples_collected_;
std::map<const char*, uint64_t> samples_per_instruction_;
std::map<cpu::Function*, uint64_t> samples_per_function_;
bool is_profiling_ = false;
bool worker_should_exit_ = false;
bool should_refresh_threads_ = false;
threading::Fence worker_fence_;
threading::Fence profiling_stop_fence_;
std::unique_ptr<threading::Thread> worker_thread_;
Timer timer_;
};
} // namespace debug
} // namespace xe
#endif // XENIA_DEBUG_PROFILER_H_

View File

@ -1,29 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_DEBUG_PROTOCOL_H_
#define XENIA_DEBUG_PROTOCOL_H_
namespace xe {
namespace debug {
namespace protocol {
template <typename T>
class Packet {
public:
protected:
int type_;
};
} // namespace protocol
} // namespace debug
} // namespace xe
#endif // XENIA_DEBUG_PROTOCOL_H_