9a07ed53eb
Now that we have most of core free of shadowing, we can enable the warning as an error to catch anything that may be remaining and also eliminate this class of logic bug entirely.
110 lines
2.8 KiB
C++
110 lines
2.8 KiB
C++
// Copyright 2018 yuzu emulator team
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <atomic>
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <thread>
|
|
|
|
#include "common/fiber.h"
|
|
#include "common/thread.h"
|
|
#include "core/hardware_properties.h"
|
|
|
|
namespace Common {
|
|
class Event;
|
|
class Fiber;
|
|
} // namespace Common
|
|
|
|
namespace Core {
|
|
|
|
class System;
|
|
|
|
class CpuManager {
|
|
public:
|
|
explicit CpuManager(System& system_);
|
|
CpuManager(const CpuManager&) = delete;
|
|
CpuManager(CpuManager&&) = delete;
|
|
|
|
~CpuManager();
|
|
|
|
CpuManager& operator=(const CpuManager&) = delete;
|
|
CpuManager& operator=(CpuManager&&) = delete;
|
|
|
|
/// Sets if emulation is multicore or single core, must be set before Initialize
|
|
void SetMulticore(bool is_multi) {
|
|
is_multicore = is_multi;
|
|
}
|
|
|
|
/// Sets if emulation is using an asynchronous GPU.
|
|
void SetAsyncGpu(bool is_async) {
|
|
is_async_gpu = is_async;
|
|
}
|
|
|
|
void Initialize();
|
|
void Shutdown();
|
|
|
|
void Pause(bool paused);
|
|
|
|
static std::function<void(void*)> GetGuestThreadStartFunc();
|
|
static std::function<void(void*)> GetIdleThreadStartFunc();
|
|
static std::function<void(void*)> GetSuspendThreadStartFunc();
|
|
void* GetStartFuncParamater();
|
|
|
|
void PreemptSingleCore(bool from_running_enviroment = true);
|
|
|
|
std::size_t CurrentCore() const {
|
|
return current_core.load();
|
|
}
|
|
|
|
private:
|
|
static void GuestThreadFunction(void* cpu_manager);
|
|
static void GuestRewindFunction(void* cpu_manager);
|
|
static void IdleThreadFunction(void* cpu_manager);
|
|
static void SuspendThreadFunction(void* cpu_manager);
|
|
|
|
void MultiCoreRunGuestThread();
|
|
void MultiCoreRunGuestLoop();
|
|
void MultiCoreRunIdleThread();
|
|
void MultiCoreRunSuspendThread();
|
|
void MultiCorePause(bool paused);
|
|
|
|
void SingleCoreRunGuestThread();
|
|
void SingleCoreRunGuestLoop();
|
|
void SingleCoreRunIdleThread();
|
|
void SingleCoreRunSuspendThread();
|
|
void SingleCorePause(bool paused);
|
|
|
|
static void ThreadStart(CpuManager& cpu_manager, std::size_t core);
|
|
|
|
void RunThread(std::size_t core);
|
|
|
|
struct CoreData {
|
|
std::shared_ptr<Common::Fiber> host_context;
|
|
std::unique_ptr<Common::Event> enter_barrier;
|
|
std::unique_ptr<Common::Event> exit_barrier;
|
|
std::atomic<bool> is_running;
|
|
std::atomic<bool> is_paused;
|
|
std::atomic<bool> initialized;
|
|
std::unique_ptr<std::thread> host_thread;
|
|
};
|
|
|
|
std::atomic<bool> running_mode{};
|
|
std::atomic<bool> paused_state{};
|
|
|
|
std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{};
|
|
|
|
bool is_async_gpu{};
|
|
bool is_multicore{};
|
|
std::atomic<std::size_t> current_core{};
|
|
std::size_t idle_count{};
|
|
static constexpr std::size_t max_cycle_runs = 5;
|
|
|
|
System& system;
|
|
};
|
|
|
|
} // namespace Core
|