2022-04-23 04:59:50 -04:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2020-01-26 13:07:22 -05:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <array>
|
2020-03-10 11:50:33 -04:00
|
|
|
#include <atomic>
|
2020-02-24 21:04:12 -05:00
|
|
|
#include <functional>
|
2020-01-26 13:07:22 -05:00
|
|
|
#include <memory>
|
2020-02-24 21:04:12 -05:00
|
|
|
#include <thread>
|
2020-07-16 13:22:55 -04:00
|
|
|
|
|
|
|
#include "common/fiber.h"
|
2022-11-21 11:31:18 -05:00
|
|
|
#include "common/polyfill_thread.h"
|
2020-07-16 13:22:55 -04:00
|
|
|
#include "common/thread.h"
|
2020-02-11 18:56:24 -05:00
|
|
|
#include "core/hardware_properties.h"
|
2020-01-26 13:07:22 -05:00
|
|
|
|
2020-02-24 21:04:12 -05:00
|
|
|
namespace Common {
|
|
|
|
class Event;
|
|
|
|
class Fiber;
|
|
|
|
} // namespace Common
|
|
|
|
|
2020-01-26 13:07:22 -05:00
|
|
|
namespace Core {
|
|
|
|
|
|
|
|
class System;
|
|
|
|
|
|
|
|
class CpuManager {
|
|
|
|
public:
|
2021-05-16 01:46:30 -04:00
|
|
|
explicit CpuManager(System& system_);
|
2020-01-26 13:07:22 -05:00
|
|
|
CpuManager(const CpuManager&) = delete;
|
|
|
|
CpuManager(CpuManager&&) = delete;
|
|
|
|
|
|
|
|
~CpuManager();
|
|
|
|
|
|
|
|
CpuManager& operator=(const CpuManager&) = delete;
|
|
|
|
CpuManager& operator=(CpuManager&&) = delete;
|
|
|
|
|
2020-03-08 22:39:41 -04:00
|
|
|
/// Sets if emulation is multicore or single core, must be set before Initialize
|
2021-05-02 22:14:15 -04:00
|
|
|
void SetMulticore(bool is_multi) {
|
|
|
|
is_multicore = is_multi;
|
2020-03-08 22:39:41 -04:00
|
|
|
}
|
2020-03-15 21:34:22 -04:00
|
|
|
|
|
|
|
/// Sets if emulation is using an asynchronous GPU.
|
2021-05-02 22:14:15 -04:00
|
|
|
void SetAsyncGpu(bool is_async) {
|
|
|
|
is_async_gpu = is_async;
|
2020-03-15 21:34:22 -04:00
|
|
|
}
|
|
|
|
|
2022-06-16 23:42:39 -04:00
|
|
|
void OnGpuReady() {
|
|
|
|
gpu_barrier->Sync();
|
|
|
|
}
|
|
|
|
|
2020-01-26 13:07:22 -05:00
|
|
|
void Initialize();
|
|
|
|
void Shutdown();
|
|
|
|
|
2022-06-26 18:52:16 -04:00
|
|
|
std::function<void()> GetGuestActivateFunc() {
|
2022-07-05 23:27:25 -04:00
|
|
|
return [this] { GuestActivate(); };
|
2022-06-26 18:52:16 -04:00
|
|
|
}
|
|
|
|
std::function<void()> GetGuestThreadFunc() {
|
2022-07-02 12:33:49 -04:00
|
|
|
return [this] { GuestThreadFunction(); };
|
|
|
|
}
|
|
|
|
std::function<void()> GetIdleThreadStartFunc() {
|
|
|
|
return [this] { IdleThreadFunction(); };
|
|
|
|
}
|
|
|
|
std::function<void()> GetShutdownThreadStartFunc() {
|
|
|
|
return [this] { ShutdownThreadFunction(); };
|
|
|
|
}
|
2020-01-26 13:07:22 -05:00
|
|
|
|
2020-03-28 15:23:28 -04:00
|
|
|
void PreemptSingleCore(bool from_running_enviroment = true);
|
2020-03-10 13:13:39 -04:00
|
|
|
|
2020-03-08 22:39:41 -04:00
|
|
|
std::size_t CurrentCore() const {
|
2020-03-10 11:50:33 -04:00
|
|
|
return current_core.load();
|
2020-03-08 22:39:41 -04:00
|
|
|
}
|
|
|
|
|
2020-02-24 21:04:12 -05:00
|
|
|
private:
|
2022-07-02 12:33:49 -04:00
|
|
|
void GuestThreadFunction();
|
|
|
|
void IdleThreadFunction();
|
|
|
|
void ShutdownThreadFunction();
|
2020-01-26 13:07:22 -05:00
|
|
|
|
2020-03-08 22:39:41 -04:00
|
|
|
void MultiCoreRunGuestThread();
|
2022-07-05 23:27:25 -04:00
|
|
|
void MultiCoreRunIdleThread();
|
2020-03-08 22:39:41 -04:00
|
|
|
|
|
|
|
void SingleCoreRunGuestThread();
|
2022-07-05 23:27:25 -04:00
|
|
|
void SingleCoreRunIdleThread();
|
2020-01-26 13:07:22 -05:00
|
|
|
|
2021-08-07 01:32:48 -04:00
|
|
|
static void ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core);
|
2020-01-26 13:07:22 -05:00
|
|
|
|
2022-07-05 23:27:25 -04:00
|
|
|
void GuestActivate();
|
2022-06-26 18:52:16 -04:00
|
|
|
void HandleInterrupt();
|
2022-06-13 18:36:30 -04:00
|
|
|
void ShutdownThread();
|
|
|
|
void RunThread(std::size_t core);
|
2020-02-24 21:04:12 -05:00
|
|
|
|
|
|
|
struct CoreData {
|
2021-03-05 20:08:17 -05:00
|
|
|
std::shared_ptr<Common::Fiber> host_context;
|
2021-08-07 01:32:48 -04:00
|
|
|
std::jthread host_thread;
|
2020-02-24 21:04:12 -05:00
|
|
|
};
|
|
|
|
|
2022-06-16 23:42:39 -04:00
|
|
|
std::unique_ptr<Common::Barrier> gpu_barrier{};
|
2020-02-24 21:04:12 -05:00
|
|
|
std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{};
|
2020-01-26 13:07:22 -05:00
|
|
|
|
2020-03-15 21:34:22 -04:00
|
|
|
bool is_async_gpu{};
|
2020-03-08 22:39:41 -04:00
|
|
|
bool is_multicore{};
|
2020-03-10 11:50:33 -04:00
|
|
|
std::atomic<std::size_t> current_core{};
|
2020-03-19 13:09:32 -04:00
|
|
|
std::size_t idle_count{};
|
2022-06-13 18:36:30 -04:00
|
|
|
std::size_t num_cores{};
|
2020-03-08 22:39:41 -04:00
|
|
|
static constexpr std::size_t max_cycle_runs = 5;
|
|
|
|
|
2020-01-26 13:07:22 -05:00
|
|
|
System& system;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace Core
|