From e2b1b059edce556fd3e9890ede7a0d97e4ce4216 Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 22 Oct 2023 17:10:25 +0300 Subject: [PATCH 1/2] core: Switch to std threading primitives --- CMakeLists.txt | 2 - src/Core/PS4/GPU/gpu_memory.cpp | 6 +- src/Core/PS4/GPU/gpu_memory.h | 3 +- src/Core/PS4/GPU/tile_manager.cpp | 6 +- .../HLE/Graphics/Objects/video_out_ctx.cpp | 70 +++++----- .../PS4/HLE/Graphics/Objects/video_out_ctx.h | 20 +-- src/Core/PS4/HLE/Graphics/graphics_ctx.h | 7 +- src/Core/PS4/HLE/Graphics/graphics_render.cpp | 22 +-- src/Core/PS4/HLE/Graphics/video_out.cpp | 2 +- .../PS4/HLE/Kernel/Objects/event_queue.cpp | 14 +- src/Core/PS4/HLE/Kernel/Objects/event_queue.h | 7 +- .../HLE/Kernel/Objects/physical_memory.cpp | 4 +- .../PS4/HLE/Kernel/Objects/physical_memory.h | 4 +- src/Core/PS4/HLE/LibKernel.cpp | 1 + src/Core/PS4/Linker.cpp | 2 +- src/Core/PS4/Linker.h | 4 +- src/Emulator/Host/controller.cpp | 4 +- src/Emulator/Host/controller.h | 4 +- src/Lib/Threads.cpp | 79 ----------- src/Lib/Threads.h | 131 ------------------ src/emulator.cpp | 12 +- src/emulator.h | 10 +- src/main.cpp | 9 +- src/vulkan_util.cpp | 4 +- 24 files changed, 98 insertions(+), 329 deletions(-) delete mode 100644 src/Lib/Threads.cpp delete mode 100644 src/Lib/Threads.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 94f9fe71..92a8b3be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,8 +83,6 @@ add_executable(shadps4 src/Core/PS4/Stubs.cpp src/Core/PS4/Stubs.h src/Core/PS4/Util/aerolib.cpp - src/Lib/Threads.cpp - src/Lib/Threads.h src/Core/PS4/HLE/Kernel/Objects/physical_memory.h src/Core/PS4/HLE/Kernel/Objects/physical_memory.cpp src/Util/string_util.cpp diff --git a/src/Core/PS4/GPU/gpu_memory.cpp b/src/Core/PS4/GPU/gpu_memory.cpp index 3e451645..e7e2fe81 100644 --- a/src/Core/PS4/GPU/gpu_memory.cpp +++ b/src/Core/PS4/GPU/gpu_memory.cpp @@ -14,7 +14,7 @@ void* GPU::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, void GPU::memorySetAllocArea(u64 virtual_addr, u64 size) { auto* gpumemory = singleton::instance(); - Lib::LockMutexGuard lock(gpumemory->m_mutex); + std::scoped_lock lock{gpumemory->m_mutex}; MemoryHeap h; h.allocated_virtual_addr = virtual_addr; @@ -80,7 +80,7 @@ void* GPU::GPUMemory::memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::Graphi int virtual_addr_num, const GPUObject& info) { auto* gpumemory = singleton::instance(); - Lib::LockMutexGuard lock(gpumemory->m_mutex); + std::scoped_lock lock{gpumemory->m_mutex}; int heap_id = gpumemory->getHeapId(virtual_addr[0], size[0]); @@ -172,7 +172,7 @@ void GPU::GPUMemory::update(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, } void GPU::GPUMemory::flushAllHeaps(HLE::Libs::Graphics::GraphicCtx* ctx) { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; int heap_id = 0; for (auto& heap : m_heaps) { diff --git a/src/Core/PS4/GPU/gpu_memory.h b/src/Core/PS4/GPU/gpu_memory.h index f7612649..90151259 100644 --- a/src/Core/PS4/GPU/gpu_memory.h +++ b/src/Core/PS4/GPU/gpu_memory.h @@ -2,6 +2,7 @@ #include #include +#include #include namespace GPU { @@ -66,7 +67,7 @@ class GPUMemory { GPUMemory() {} virtual ~GPUMemory() {} int getHeapId(u64 vaddr, u64 size); - Lib::Mutex m_mutex; + std::mutex m_mutex; std::vector m_heaps; void* memoryCreateObj(u64 submit_id, HLE::Libs::Graphics::GraphicCtx* ctx, /*CommandBuffer* buffer*/ void* todo, const u64* virtual_addr, const u64* size, int virtual_addr_num, const GPUObject& info); diff --git a/src/Core/PS4/GPU/tile_manager.cpp b/src/Core/PS4/GPU/tile_manager.cpp index 3687f2b8..ba072770 100644 --- a/src/Core/PS4/GPU/tile_manager.cpp +++ b/src/Core/PS4/GPU/tile_manager.cpp @@ -1,6 +1,6 @@ #include "tile_manager.h" -#include "Lib/Threads.h" #include "Emulator/Util/singleton.h" +#include namespace GPU { @@ -10,7 +10,7 @@ class TileManager { public: TileManager(){} virtual ~TileManager() { } - Lib::Mutex m_mutex; + std::mutex m_mutex; }; class TileManager32 { @@ -145,7 +145,7 @@ void convertTileToLinear(void* dst, const void* src,u32 width, u32 height, bool auto* g_TileManager = singleton::instance(); - Lib::LockMutexGuard lock(g_TileManager->m_mutex); + std::scoped_lock lock{g_TileManager->m_mutex}; for (u32 y = 0; y < height; y++) { u32 x = 0; diff --git a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp index 2de9139b..9d1401d9 100644 --- a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp +++ b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp @@ -12,7 +12,7 @@ void VideoOutCtx::Init(u32 width, u32 height) { m_video_out_ctx.m_resolution.paneHeight = height; } int VideoOutCtx::Open() { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; int handle = -1; @@ -30,7 +30,7 @@ int VideoOutCtx::Open() { return handle; } void VideoOutCtx::Close(s32 handle) { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; m_video_out_ctx.isOpened = false; @@ -55,18 +55,19 @@ void VideoOutCtx::Close(s32 handle) { } VideoConfigInternal* VideoOutCtx::getCtx(int handle) { - if (handle != 1) return nullptr; + if (handle != 1) [[unlikely]] { + return nullptr; + } return &m_video_out_ctx; // assuming that it's the only ctx TODO check if we need more } void FlipQueue::getFlipStatus(VideoConfigInternal* cfg, SceVideoOutFlipStatus* out) { - Lib::LockMutexGuard lock(m_mutex); - + std::scoped_lock lock(m_mutex); *out = cfg->m_flip_status; } bool FlipQueue::submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg) { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; if (m_requests.size() >= 2) { return false; @@ -83,52 +84,53 @@ bool FlipQueue::submitFlip(VideoConfigInternal* cfg, s32 index, s64 flip_arg) { cfg->m_flip_status.flipPendingNum = static_cast(m_requests.size()); cfg->m_flip_status.gcQueueNum = 0; - m_submit_cond.SignalCondVar(); + m_submit_cond.notify_one(); return true; } bool FlipQueue::flip(u32 micros) { - m_mutex.LockMutex(); - if (m_requests.size() == 0) { - m_submit_cond.WaitCondVarFor(&m_mutex, micros); - - if (m_requests.size() == 0) { - m_mutex.UnlockMutex(); - return false; + const auto request = [&]() -> Request* { + std::unique_lock lock{m_mutex}; + m_submit_cond.wait_for(lock, std::chrono::microseconds(micros), + [&] { return !m_requests.empty(); }); + if (m_requests.empty()) { + return nullptr; } + return &m_requests.at(0); // Process first request + }(); + + if (!request) { + return false; } - auto request = m_requests.at(0); // proceed first request - m_mutex.UnlockMutex(); - - auto* buffer = request.cfg->buffers[request.index].buffer_render; + const auto buffer = request->cfg->buffers[request->index].buffer_render; Emu::DrawBuffer(buffer); - m_mutex.LockMutex(); + std::scoped_lock lock{m_mutex}; - request.cfg->m_mutex.LockMutex(); - for (auto& flip_eq : request.cfg->m_flip_evtEq) { - if (flip_eq != nullptr) { - flip_eq->triggerEvent(SCE_VIDEO_OUT_EVENT_FLIP, HLE::Kernel::Objects::EVFILT_VIDEO_OUT, reinterpret_cast(request.flip_arg)); + { + std::scoped_lock cfg_lock{request->cfg->m_mutex}; + for (auto& flip_eq : request->cfg->m_flip_evtEq) { + if (flip_eq != nullptr) { + flip_eq->triggerEvent(SCE_VIDEO_OUT_EVENT_FLIP, HLE::Kernel::Objects::EVFILT_VIDEO_OUT, + reinterpret_cast(request->flip_arg)); + } } } - request.cfg->m_mutex.UnlockMutex(); m_requests.erase(m_requests.begin()); - m_done_cond.SignalCondVar(); + m_done_cond.notify_one(); - request.cfg->m_flip_status.count++; + request->cfg->m_flip_status.count++; //TODO request.cfg->m_flip_status.processTime = LibKernel::KernelGetProcessTime(); - request.cfg->m_flip_status.tsc = HLE::Libs::LibKernel::sceKernelReadTsc(); - request.cfg->m_flip_status.submitTsc = request.submit_tsc; - request.cfg->m_flip_status.flipArg = request.flip_arg; - request.cfg->m_flip_status.currentBuffer = request.index; - request.cfg->m_flip_status.flipPendingNum = static_cast(m_requests.size()); - - m_mutex.UnlockMutex(); + request->cfg->m_flip_status.tsc = HLE::Libs::LibKernel::sceKernelReadTsc(); + request->cfg->m_flip_status.submitTsc = request->submit_tsc; + request->cfg->m_flip_status.flipArg = request->flip_arg; + request->cfg->m_flip_status.currentBuffer = request->index; + request->cfg->m_flip_status.flipPendingNum = static_cast(m_requests.size()); return false; } -}; // namespace HLE::Graphics::Objects +}; // namespace HLE::Graphics::Objects diff --git a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h index 3aec2d5a..07f301ac 100644 --- a/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h +++ b/src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h @@ -1,6 +1,8 @@ #pragma once + +#include +#include #include -#include #include #include @@ -17,7 +19,7 @@ struct VideoOutBufferInfo { }; struct VideoConfigInternal { - Lib::Mutex m_mutex; + std::mutex m_mutex; SceVideoOutResolutionStatus m_resolution; bool isOpened = false; SceVideoOutFlipStatus m_flip_status; @@ -45,9 +47,9 @@ class FlipQueue { uint64_t submit_tsc; }; - Lib::Mutex m_mutex; - Lib::ConditionVariable m_submit_cond; - Lib::ConditionVariable m_done_cond; + std::mutex m_mutex; + std::condition_variable m_submit_cond; + std::condition_variable m_done_cond; std::vector m_requests; }; @@ -62,16 +64,16 @@ class VideoOutCtx { VideoConfigInternal* getCtx(int handle); FlipQueue& getFlipQueue() { return m_flip_queue; } HLE::Libs::Graphics::GraphicCtx* getGraphicCtx() { - Lib::LockMutexGuard lock(m_mutex); - - if (m_graphic_ctx == nullptr) { + std::scoped_lock lock{m_mutex}; + + if (!m_graphic_ctx) { m_graphic_ctx = Emu::getGraphicCtx(); } return m_graphic_ctx; } private: - Lib::Mutex m_mutex; + std::mutex m_mutex; VideoConfigInternal m_video_out_ctx; FlipQueue m_flip_queue; HLE::Libs::Graphics::GraphicCtx* m_graphic_ctx = nullptr; diff --git a/src/Core/PS4/HLE/Graphics/graphics_ctx.h b/src/Core/PS4/HLE/Graphics/graphics_ctx.h index 5b7eb493..051949b5 100644 --- a/src/Core/PS4/HLE/Graphics/graphics_ctx.h +++ b/src/Core/PS4/HLE/Graphics/graphics_ctx.h @@ -2,13 +2,12 @@ #include #include - -#include "Lib/Threads.h" +#include namespace HLE::Libs::Graphics { struct VulkanCommandPool { - Lib::Mutex mutex; + std::mutex mutex; VkCommandPool pool = nullptr; VkCommandBuffer* buffers = nullptr; VkFence* fences = nullptr; @@ -18,7 +17,7 @@ struct VulkanCommandPool { }; struct VulkanQueueInfo { - Lib::Mutex* mutex = nullptr; + std::mutex* mutex = nullptr; u32 family = static_cast(-1); u32 index = static_cast(-1); VkQueue vk_queue = nullptr; diff --git a/src/Core/PS4/HLE/Graphics/graphics_render.cpp b/src/Core/PS4/HLE/Graphics/graphics_render.cpp index 22d5c651..e51e3721 100644 --- a/src/Core/PS4/HLE/Graphics/graphics_render.cpp +++ b/src/Core/PS4/HLE/Graphics/graphics_render.cpp @@ -14,7 +14,7 @@ void GPU::renderCreateCtx() { void GPU::CommandBuffer::allocateBuffer() { m_pool = g_command_pool.getPool(m_queue); - Lib::LockMutexGuard lock(m_pool->mutex); + std::scoped_lock lock{m_pool->mutex}; for (uint32_t i = 0; i < m_pool->buffers_count; i++) { if (!m_pool->busy[i]) { @@ -27,7 +27,7 @@ void GPU::CommandBuffer::allocateBuffer() { } void GPU::CommandBuffer::freeBuffer() { - Lib::LockMutexGuard lock(m_pool->mutex); + std::scoped_lock lock{m_pool->mutex}; waitForFence(); @@ -91,17 +91,8 @@ void GPU::CommandBuffer::executeWithSemaphore() { auto* render_ctx = singleton::instance(); const auto& queue = render_ctx->getGraphicCtx()->queues[m_queue]; - - if (queue.mutex != nullptr) { - queue.mutex->LockMutex(); - } - auto result = vkQueueSubmit(queue.vk_queue, 1, &submit_info, fence); - if (queue.mutex != nullptr) { - queue.mutex->LockMutex(); - } - m_execute = true; if (result != VK_SUCCESS) { @@ -126,17 +117,8 @@ void GPU::CommandBuffer::execute() { auto* render_ctx = singleton::instance(); const auto& queue = render_ctx->getGraphicCtx()->queues[m_queue]; - - if (queue.mutex != nullptr) { - queue.mutex->LockMutex(); - } - auto result = vkQueueSubmit(queue.vk_queue, 1, &submit_info, fence); - if (queue.mutex != nullptr) { - queue.mutex->UnlockMutex(); - } - m_execute = true; if (result != VK_SUCCESS) { diff --git a/src/Core/PS4/HLE/Graphics/video_out.cpp b/src/Core/PS4/HLE/Graphics/video_out.cpp index a51e2c6e..f8503edd 100644 --- a/src/Core/PS4/HLE/Graphics/video_out.cpp +++ b/src/Core/PS4/HLE/Graphics/video_out.cpp @@ -94,7 +94,7 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(LibKernel::EventQueues::SceKernelEqueue if (ctx == nullptr) { return SCE_VIDEO_OUT_ERROR_INVALID_HANDLE; } - Lib::LockMutexGuard lock(ctx->m_mutex); + std::scoped_lock lock(ctx->m_mutex); if (eq == nullptr) { return SCE_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE; diff --git a/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp b/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp index 6eff9949..521cd432 100644 --- a/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp +++ b/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp @@ -8,7 +8,7 @@ namespace HLE::Kernel::Objects { EqueueInternal::~EqueueInternal() {} int EqueueInternal::addEvent(const EqueueEvent& event) { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; if (m_events.size() > 0) { BREAKPOINT(); @@ -24,7 +24,7 @@ int EqueueInternal::addEvent(const EqueueEvent& event) { } int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) { - Lib::LockMutexGuard lock(m_mutex); + std::unique_lock lock{m_mutex}; u32 timeElapsed = 0; Lib::Timer t; @@ -38,9 +38,9 @@ int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) { } if (micros == 0) { - m_cond.WaitCondVar(&m_mutex); + m_cond.wait(lock); } else { - m_cond.WaitCondVarFor(&m_mutex, micros - timeElapsed); + m_cond.wait_for(lock, std::chrono::microseconds(micros - timeElapsed)); } timeElapsed = static_cast(t.GetTimeSec() * 1000000.0); @@ -50,7 +50,7 @@ int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) { } bool EqueueInternal::triggerEvent(u64 ident, s16 filter, void* trigger_data) { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; if (m_events.size() > 1) { BREAKPOINT(); // we currently support one event @@ -63,14 +63,12 @@ bool EqueueInternal::triggerEvent(u64 ident, s16 filter, void* trigger_data) { event.isTriggered = true; } - m_cond.SignalCondVar(); + m_cond.notify_one(); return true; } int EqueueInternal::getTriggeredEvents(SceKernelEvent* ev, int num) { - Lib::LockMutexGuard lock(m_mutex); - int ret = 0; if (m_events.size() > 1) { diff --git a/src/Core/PS4/HLE/Kernel/Objects/event_queue.h b/src/Core/PS4/HLE/Kernel/Objects/event_queue.h index b24151d5..66ebe33f 100644 --- a/src/Core/PS4/HLE/Kernel/Objects/event_queue.h +++ b/src/Core/PS4/HLE/Kernel/Objects/event_queue.h @@ -1,6 +1,7 @@ #pragma once + #include -#include +#include #include #include @@ -71,8 +72,8 @@ class EqueueInternal { int getTriggeredEvents(SceKernelEvent* ev, int num); private: std::string m_name; - Lib::Mutex m_mutex; + std::mutex m_mutex; std::vector m_events; - Lib::ConditionVariable m_cond; + std::condition_variable m_cond; }; }; // namespace HLE::Kernel::Objects \ No newline at end of file diff --git a/src/Core/PS4/HLE/Kernel/Objects/physical_memory.cpp b/src/Core/PS4/HLE/Kernel/Objects/physical_memory.cpp index 50f60f3f..a8a41d62 100644 --- a/src/Core/PS4/HLE/Kernel/Objects/physical_memory.cpp +++ b/src/Core/PS4/HLE/Kernel/Objects/physical_memory.cpp @@ -5,7 +5,7 @@ namespace HLE::Kernel::Objects { static u64 AlignUp(u64 pos, u64 align) { return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos); } bool PhysicalMemory::Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment, u64* physAddrOut, int memoryType) { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; u64 find_free_pos = 0; // iterate through allocated blocked and find the next free position @@ -40,7 +40,7 @@ bool PhysicalMemory::Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignmen return false; } bool PhysicalMemory::Map(u64 virtual_addr, u64 phys_addr, u64 len, int prot, VirtualMemory::MemoryMode cpu_mode, GPU::MemoryMode gpu_mode) { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; for (auto& b : m_allocatedBlocks) { if (phys_addr >= b.start_addr && phys_addr < b.start_addr + b.size) { if (b.map_virtual_addr != 0 || b.map_size != 0) { diff --git a/src/Core/PS4/HLE/Kernel/Objects/physical_memory.h b/src/Core/PS4/HLE/Kernel/Objects/physical_memory.h index e2e9ce49..7e509bf3 100644 --- a/src/Core/PS4/HLE/Kernel/Objects/physical_memory.h +++ b/src/Core/PS4/HLE/Kernel/Objects/physical_memory.h @@ -2,8 +2,8 @@ #include #include #include +#include #include -#include "Lib/Threads.h" namespace HLE::Kernel::Objects { @@ -28,7 +28,7 @@ class PhysicalMemory { private: std::vector m_allocatedBlocks; - Lib::Mutex m_mutex; + std::mutex m_mutex; }; } // namespace HLE::Kernel::Objects \ No newline at end of file diff --git a/src/Core/PS4/HLE/LibKernel.cpp b/src/Core/PS4/HLE/LibKernel.cpp index 81252174..a9646091 100644 --- a/src/Core/PS4/HLE/LibKernel.cpp +++ b/src/Core/PS4/HLE/LibKernel.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "Emulator/Util/singleton.h" #include "../Loader/Elf.h" diff --git a/src/Core/PS4/Linker.cpp b/src/Core/PS4/Linker.cpp index bbd97cf7..0748fdd0 100644 --- a/src/Core/PS4/Linker.cpp +++ b/src/Core/PS4/Linker.cpp @@ -70,7 +70,7 @@ static std::string encodeId(u64 nVal) } Module* Linker::LoadModule(const std::string& elf_name) { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; auto* m = new Module; m->linker = this; m->elf = new Elf; diff --git a/src/Core/PS4/Linker.h b/src/Core/PS4/Linker.h index e34cce04..e777d61b 100644 --- a/src/Core/PS4/Linker.h +++ b/src/Core/PS4/Linker.h @@ -1,9 +1,9 @@ #pragma once #include +#include #include "Loader/Elf.h" #include "Loader/SymbolsResolver.h" -#include "Lib/Threads.h" struct DynamicModuleInfo; class Linker; @@ -130,5 +130,5 @@ public: std::vector m_modules; SymbolsResolver* m_HLEsymbols = nullptr; - Lib::Mutex m_mutex; + std::mutex m_mutex; }; \ No newline at end of file diff --git a/src/Emulator/Host/controller.cpp b/src/Emulator/Host/controller.cpp index 04ae4a9a..6930c969 100644 --- a/src/Emulator/Host/controller.cpp +++ b/src/Emulator/Host/controller.cpp @@ -5,7 +5,7 @@ GameController::GameController() { m_states_num = 0; m_last_state = State(); } void GameController::readState(State* state, bool* isConnected, int* connectedCount) { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; *isConnected = m_connected; *connectedCount = m_connected_count; @@ -37,7 +37,7 @@ void GameController::addState(const State& state) { } void GameController::checKButton(int id, u32 button, bool isPressed) { - Lib::LockMutexGuard lock(m_mutex); + std::scoped_lock lock{m_mutex}; auto state = getLastState(); if (isPressed) { state.buttonsState |= button; diff --git a/src/Emulator/Host/controller.h b/src/Emulator/Host/controller.h index 4158ef3c..f2c1db8f 100644 --- a/src/Emulator/Host/controller.h +++ b/src/Emulator/Host/controller.h @@ -1,6 +1,6 @@ #pragma once #include -#include "Lib/Threads.h" +#include namespace Emulator::Host::Controller { struct State { @@ -21,7 +21,7 @@ class GameController { private: - Lib::Mutex m_mutex; + std::mutex m_mutex; bool m_connected = false; State m_last_state; int m_connected_count = 0; diff --git a/src/Lib/Threads.cpp b/src/Lib/Threads.cpp deleted file mode 100644 index bd391f5e..00000000 --- a/src/Lib/Threads.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "Threads.h" - -#include - -static std::thread::id g_main_thread; -static int g_main_thread_int; -static std::atomic g_thread_counter = 0; - -void Lib::InitThreads() { - g_main_thread = std::this_thread::get_id(); - g_main_thread_int = Lib::Thread::GetThreadIdUnique(); -} - -Lib::Thread::Thread(thread_func_t func, void* arg) { - m_thread = new ThreadStructInternal(func, arg); - while (!m_thread->started) { - SleepThreadMicro(1000); - } -} - -Lib::Thread::~Thread() { delete m_thread; } - -void Lib::Thread::JoinThread() { m_thread->m_thread.join(); } - -void Lib::Thread::DetachThread() { m_thread->m_thread.detach(); } - -std::string Lib::Thread::GetId() const { - std::stringstream ss; - ss << m_thread->m_thread.get_id(); - return ss.str().c_str(); -} - -int Lib::Thread::GetUniqueId() const { return m_thread->unique_id; } - -void Lib::Thread::SleepThread(u32 millis) { std::this_thread::sleep_for(std::chrono::milliseconds(millis)); } - -void Lib::Thread::SleepThreadMicro(u32 micros) { std::this_thread::sleep_for(std::chrono::microseconds(micros)); } - -void Lib::Thread::SleepThreadNano(u64 nanos) { std::this_thread::sleep_for(std::chrono::nanoseconds(nanos)); } - -bool Lib::Thread::IsMainThread() { return g_main_thread == std::this_thread::get_id(); } - -std::string Lib::Thread::GetThreadId() { - std::stringstream ss; - ss << std::this_thread::get_id(); - return ss.str().c_str(); -} - -int Lib::Thread::GetThreadIdUnique() { - static thread_local int tid = ++g_thread_counter; - return tid; -} - -Lib::Mutex::Mutex() { m_mutex = new MutexStructInternal(); } - -Lib::Mutex::~Mutex() { delete m_mutex; } - -void Lib::Mutex::LockMutex() { EnterCriticalSection(&m_mutex->m_cs); } - -void Lib::Mutex::UnlockMutex() { LeaveCriticalSection(&m_mutex->m_cs); } - -bool Lib::Mutex::TryLockMutex() { return (TryEnterCriticalSection(&m_mutex->m_cs) != 0); } - -Lib::ConditionVariable::ConditionVariable() { m_cond_var = new ConditionVariableStructInternal(); } - -Lib::ConditionVariable::~ConditionVariable() { delete m_cond_var; } - -void Lib::ConditionVariable::WaitCondVar(Mutex* mutex) { SleepConditionVariableCS(&m_cond_var->m_cv, &mutex->m_mutex->m_cs, INFINITE); } - -bool Lib::ConditionVariable::WaitCondVarFor(Mutex* mutex, u32 micros) { - bool ok = false; - ok = !(SleepConditionVariableCS(&m_cond_var->m_cv, &mutex->m_mutex->m_cs, (micros < 1000 ? 1 : micros / 1000)) == 0 && - GetLastError() == ERROR_TIMEOUT); - return ok; -} - -void Lib::ConditionVariable::SignalCondVar() { WakeConditionVariable(&m_cond_var->m_cv); } - -void Lib::ConditionVariable::SignalCondVarAll() { WakeAllConditionVariable(&m_cond_var->m_cv); } diff --git a/src/Lib/Threads.h b/src/Lib/Threads.h deleted file mode 100644 index 3773eaf5..00000000 --- a/src/Lib/Threads.h +++ /dev/null @@ -1,131 +0,0 @@ -#pragma once - -#include "windows.h" -#include -#include -#include -#include -#include - -#include "../types.h" - - -namespace Lib { -using thread_func_t = void (*)(void*); - -void InitThreads(); - -struct ThreadStructInternal; -struct MutexStructInternal; -struct ConditionVariableStructInternal; - -class Thread { - public: - Thread(thread_func_t func, void* arg); - virtual ~Thread(); - - void JoinThread(); - void DetachThread(); - - std::string GetId() const; - int GetUniqueId() const; - - static void SleepThread(u32 millis); - static void SleepThreadMicro(u32 micros); - static void SleepThreadNano(u64 nanos); - static bool IsMainThread(); - - // Get current thread id (reusable id) - static std::string GetThreadId(); - - // Get current thread id (unique id) - static int GetThreadIdUnique(); - - public: - Thread(const Thread&) = delete; - Thread& operator=(const Thread&) = delete; - Thread(Thread&&) = delete; - Thread& operator=(Thread&&) = delete; - - private: - ThreadStructInternal* m_thread; -}; - -struct ThreadStructInternal { - ThreadStructInternal(thread_func_t f, void* a) : func(f), arg(a), m_thread(&Run, this) {} - - static void Run(ThreadStructInternal* t) { - t->unique_id = Lib::Thread::GetThreadIdUnique(); - t->started = true; - t->func(t->arg); - } - - thread_func_t func; - void* arg; - std::atomic_bool started = false; - int unique_id = 0; - std::thread m_thread; -}; - -class Mutex { - public: - Mutex(); - virtual ~Mutex(); - - void LockMutex(); - void UnlockMutex(); - bool TryLockMutex(); - - friend class ConditionVariable; - - public: - Mutex(const Mutex&) = delete; - Mutex& operator=(const Mutex&) = delete; - Mutex(Mutex&&) = delete; - Mutex& operator=(Mutex&&) = delete; - - private: - MutexStructInternal* m_mutex; -}; - -struct MutexStructInternal { - MutexStructInternal() { InitializeCriticalSectionAndSpinCount(&m_cs, 4000); } - ~MutexStructInternal() { DeleteCriticalSection(&m_cs); } - CRITICAL_SECTION m_cs{}; -}; -class ConditionVariable { - public: - ConditionVariable(); - virtual ~ConditionVariable(); - - void WaitCondVar(Mutex* mutex); - bool WaitCondVarFor(Mutex* mutex, u32 micros); - void SignalCondVar(); - void SignalCondVarAll(); - - private: - ConditionVariableStructInternal* m_cond_var; -}; - -struct ConditionVariableStructInternal { - ConditionVariableStructInternal() { InitializeConditionVariable(&m_cv); } - ~ConditionVariableStructInternal() = default; - CONDITION_VARIABLE m_cv{}; -}; - -class LockMutexGuard { - public: - explicit LockMutexGuard(Mutex& m) : m_mutex(m) { m_mutex.LockMutex(); } - - ~LockMutexGuard() { m_mutex.UnlockMutex(); } - - private: - Mutex& m_mutex; - - public: - LockMutexGuard(const LockMutexGuard&) = delete; - LockMutexGuard& operator=(const LockMutexGuard&) = delete; - LockMutexGuard(LockMutexGuard&&) noexcept = delete; - LockMutexGuard& operator=(LockMutexGuard&&) noexcept = delete; -}; -} // namespace Lib \ No newline at end of file diff --git a/src/emulator.cpp b/src/emulator.cpp index 41925f6a..7e67849d 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -22,10 +22,10 @@ void emuInit(u32 width, u32 height) { void checkAndWaitForGraphicsInit() { auto* window_ctx = singleton::instance(); - Lib::LockMutexGuard lock(window_ctx->m_mutex); + std::unique_lock lock{window_ctx->m_mutex}; while (!window_ctx->m_is_graphic_initialized) { - window_ctx->m_graphic_initialized_cond.WaitCondVar(&window_ctx->m_mutex); + window_ctx->m_graphic_initialized_cond.wait(lock); } } static void CreateSdlWindow(WindowCtx* ctx) { @@ -51,15 +51,14 @@ static void CreateSdlWindow(WindowCtx* ctx) { } void emuRun() { auto* window_ctx = singleton::instance(); - window_ctx->m_mutex.LockMutex(); { // init window and wait until init finishes + std::scoped_lock lock{window_ctx->m_mutex}; CreateSdlWindow(window_ctx); Graphics::Vulkan::vulkanCreate(window_ctx); window_ctx->m_is_graphic_initialized = true; - window_ctx->m_graphic_initialized_cond.SignalCondVar(); + window_ctx->m_graphic_initialized_cond.notify_one(); } - window_ctx->m_mutex.UnlockMutex(); bool exit_loop = false; @@ -99,8 +98,7 @@ void emuRun() { HLE::Libs::Graphics::GraphicCtx* getGraphicCtx() { auto* window_ctx = singleton::instance(); - Lib::LockMutexGuard lock(window_ctx->m_mutex); - + std::scoped_lock lock{window_ctx->m_mutex}; return &window_ctx->m_graphic_ctx; } diff --git a/src/emulator.h b/src/emulator.h index a929250d..7842faae 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -1,8 +1,10 @@ #pragma once + #include -#include #include +#include +#include #include namespace Emu { @@ -57,9 +59,9 @@ struct VulkanSwapchain { struct WindowCtx { HLE::Libs::Graphics::GraphicCtx m_graphic_ctx; - Lib::Mutex m_mutex; + std::mutex m_mutex; bool m_is_graphic_initialized = false; - Lib::ConditionVariable m_graphic_initialized_cond; + std::condition_variable m_graphic_initialized_cond; SDL_Window* m_window = nullptr; bool is_window_hidden = true; VkSurfaceKHR m_surface = nullptr; @@ -69,7 +71,7 @@ struct WindowCtx { struct EmuPrivate { EmuPrivate() = default; - Lib::Mutex m_mutex; + std::mutex m_mutex; HLE::Libs::Graphics::GraphicCtx* m_graphic_ctx = nullptr; void* data1 = nullptr; void* data2 = nullptr; diff --git a/src/main.cpp b/src/main.cpp index fa9b7bee..172ede3a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,10 +31,10 @@ #include #include #include +#include #include "Core/PS4/HLE/Libs.h" #include "Core/PS4/Linker.h" -#include "Lib/Threads.h" #include "Emulator/Util\singleton.h" #include "discord.h" @@ -50,25 +50,22 @@ int main(int argc, char* argv[]) { auto height = Config::getScreenHeight(); Emu::emuInit(width, height); HLE::Libs::Graphics::VideoOut::videoOutInit(width, height); - Lib::InitThreads(); const char* const path = argv[1]; // argument 1 is the path of self file to boot auto* linker = singleton::instance(); HLE::Libs::Init_HLE_Libs(linker->getHLESymbols()); auto* module = linker->LoadModule(path); // load main executable - Lib::Thread mainthread( - [](void*) { + std::jthread mainthread( + [](std::stop_token stop_token, void*) { auto* linker = singleton::instance(); linker->Execute(); }, nullptr); - mainthread.DetachThread(); Discord::RPC discordRPC; discordRPC.init(); discordRPC.update(Discord::RPCStatus::Idling, ""); Emu::emuRun(); - mainthread.JoinThread(); #if 0 // Setup SDL diff --git a/src/vulkan_util.cpp b/src/vulkan_util.cpp index 9c1f21aa..f414a7f0 100644 --- a/src/vulkan_util.cpp +++ b/src/vulkan_util.cpp @@ -81,8 +81,6 @@ void Graphics::Vulkan::vulkanCreate(Emu::WindowCtx* ctx) { Emu::VulkanSwapchain* Graphics::Vulkan::vulkanCreateSwapchain(HLE::Libs::Graphics::GraphicCtx* ctx, u32 image_count) { auto* window_ctx = singleton::instance(); - Lib::LockMutexGuard lock(window_ctx->m_mutex); - auto* s = new Emu::VulkanSwapchain; VkExtent2D extent{}; @@ -189,7 +187,7 @@ void Graphics::Vulkan::vulkanCreateQueues(HLE::Libs::Graphics::GraphicCtx* ctx, ctx->queues[id].index = info.index; vkGetDeviceQueue(ctx->m_device, ctx->queues[id].family, ctx->queues[id].index, &ctx->queues[id].vk_queue); if (with_mutex) { - ctx->queues[id].mutex = new Lib::Mutex; + ctx->queues[id].mutex = new std::mutex; } }; From ba299c4c0097af2f6297bd086362aba4b477280d Mon Sep 17 00:00:00 2001 From: GPUCode Date: Sun, 22 Oct 2023 17:17:43 +0300 Subject: [PATCH 2/2] core: Remove Timer in favour of std::chrono --- CMakeLists.txt | 2 +- .../PS4/HLE/Kernel/Objects/event_queue.cpp | 13 +-- src/Lib/Timer.cpp | 103 ------------------ src/Lib/Timer.h | 34 ------ 4 files changed, 7 insertions(+), 145 deletions(-) delete mode 100644 src/Lib/Timer.cpp delete mode 100644 src/Lib/Timer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 92a8b3be..348fa510 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -96,7 +96,7 @@ add_executable(shadps4 src/Core/PS4/HLE/Kernel/cpu_management.cpp src/Core/PS4/HLE/Kernel/cpu_management.h - "src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Core/PS4/Util/aerolib.h" "src/Core/PS4/Loader/SymbolsResolver.h" "src/Core/PS4/Loader/SymbolsResolver.cpp" "src/Core/PS4/HLE/Libs.cpp" "src/Core/PS4/HLE/Libs.h" "src/Core/PS4/HLE/LibC.cpp" "src/Core/PS4/HLE/LibC.h" "src/Lib/Timer.cpp" "src/Lib/Timer.h" "src/Core/PS4/HLE/LibKernel.cpp" "src/Core/PS4/HLE/LibKernel.h" "src/Core/PS4/HLE/LibSceGnmDriver.cpp" "src/Core/PS4/HLE/LibSceGnmDriver.h" "src/Core/PS4/HLE/Kernel/ThreadManagement.cpp" "src/Core/PS4/HLE/Kernel/ThreadManagement.h" "src/Core/PS4/HLE/ErrorCodes.h" "src/debug.h" "src/Core/PS4/HLE/Kernel/memory_management.cpp" "src/Core/PS4/HLE/Kernel/memory_management.h" "src/Core/PS4/GPU/gpu_memory.cpp" "src/Core/PS4/GPU/gpu_memory.h" "src/emulator.cpp" "src/emulator.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h" "src/Core/PS4/HLE/Graphics/graphics_ctx.h" "src/vulkan_util.cpp" "src/vulkan_util.h" "src/Core/PS4/GPU/video_out_buffer.cpp" "src/Core/PS4/GPU/video_out_buffer.h" "src/Core/PS4/HLE/Graphics/graphics_render.cpp" "src/Core/PS4/HLE/Graphics/graphics_render.h" "src/Core/PS4/GPU/tile_manager.cpp" "src/Core/PS4/GPU/tile_manager.h" "src/version.h" "src/Emulator/HLE/Libraries/LibSystemService/system_service.cpp" "src/Emulator/HLE/Libraries/LibSystemService/system_service.h" "src/Emulator/HLE/Libraries/LibKernel/FileSystem/meta_file_system.h" "src/Emulator/HLE/Libraries/LibKernel/FileSystem/meta_file_system.cpp") + "src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Core/PS4/Util/aerolib.h" "src/Core/PS4/Loader/SymbolsResolver.h" "src/Core/PS4/Loader/SymbolsResolver.cpp" "src/Core/PS4/HLE/Libs.cpp" "src/Core/PS4/HLE/Libs.h" "src/Core/PS4/HLE/LibC.cpp" "src/Core/PS4/HLE/LibC.h" "src/Core/PS4/HLE/LibKernel.cpp" "src/Core/PS4/HLE/LibKernel.h" "src/Core/PS4/HLE/LibSceGnmDriver.cpp" "src/Core/PS4/HLE/LibSceGnmDriver.h" "src/Core/PS4/HLE/Kernel/ThreadManagement.cpp" "src/Core/PS4/HLE/Kernel/ThreadManagement.h" "src/Core/PS4/HLE/ErrorCodes.h" "src/debug.h" "src/Core/PS4/HLE/Kernel/memory_management.cpp" "src/Core/PS4/HLE/Kernel/memory_management.h" "src/Core/PS4/GPU/gpu_memory.cpp" "src/Core/PS4/GPU/gpu_memory.h" "src/emulator.cpp" "src/emulator.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.h" "src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.cpp" "src/Core/PS4/HLE/Graphics/Objects/video_out_ctx.h" "src/Core/PS4/HLE/Graphics/graphics_ctx.h" "src/vulkan_util.cpp" "src/vulkan_util.h" "src/Core/PS4/GPU/video_out_buffer.cpp" "src/Core/PS4/GPU/video_out_buffer.h" "src/Core/PS4/HLE/Graphics/graphics_render.cpp" "src/Core/PS4/HLE/Graphics/graphics_render.h" "src/Core/PS4/GPU/tile_manager.cpp" "src/Core/PS4/GPU/tile_manager.h" "src/version.h" "src/Emulator/HLE/Libraries/LibSystemService/system_service.cpp" "src/Emulator/HLE/Libraries/LibSystemService/system_service.h" "src/Emulator/HLE/Libraries/LibKernel/FileSystem/meta_file_system.h" "src/Emulator/HLE/Libraries/LibKernel/FileSystem/meta_file_system.cpp") find_package(OpenGL REQUIRED) target_link_libraries(shadps4 PUBLIC fmt mincore spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY} vulkan-1 spirv-tools-opt spirv-tools) diff --git a/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp b/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp index 521cd432..d1a68cc1 100644 --- a/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp +++ b/src/Core/PS4/HLE/Kernel/Objects/event_queue.cpp @@ -1,9 +1,8 @@ #include "event_queue.h" - -#include - #include "debug.h" +#include + namespace HLE::Kernel::Objects { EqueueInternal::~EqueueInternal() {} @@ -26,9 +25,8 @@ int EqueueInternal::addEvent(const EqueueEvent& event) { int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) { std::unique_lock lock{m_mutex}; - u32 timeElapsed = 0; - Lib::Timer t; - t.Start(); + u64 timeElapsed = 0; + const auto start = std::chrono::high_resolution_clock::now(); for (;;) { int ret = getTriggeredEvents(ev, num); @@ -43,7 +41,8 @@ int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) { m_cond.wait_for(lock, std::chrono::microseconds(micros - timeElapsed)); } - timeElapsed = static_cast(t.GetTimeSec() * 1000000.0); + const auto end = std::chrono::high_resolution_clock::now(); + timeElapsed = std::chrono::duration_cast(end - start).count(); } return 0; diff --git a/src/Lib/Timer.cpp b/src/Lib/Timer.cpp deleted file mode 100644 index 3dd1d251..00000000 --- a/src/Lib/Timer.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include "Timer.h" - -#ifdef _WIN64 -#include -#endif - -Lib::Timer::Timer() { -#ifdef _WIN64 - LARGE_INTEGER f; - QueryPerformanceFrequency(&f); - m_Frequency = f.QuadPart; -#else -#error Unimplemented Timer constructor -#endif -} - -void Lib::Timer::Start() { -#ifdef _WIN64 - LARGE_INTEGER c; - QueryPerformanceCounter(&c); - m_StartTime = c.QuadPart; -#else -#error Unimplemented Timer::Start() -#endif - m_is_timer_paused = false; -} - -void Lib::Timer::Pause() { -#ifdef _WIN64 - LARGE_INTEGER c; - QueryPerformanceCounter(&c); - m_PauseTime = c.QuadPart; -#else -#error Unimplemented Timer::Pause() -#endif - m_is_timer_paused = true; -} - -void Lib::Timer::Resume() { - u64 current_time = 0; -#ifdef _WIN64 - LARGE_INTEGER c; - QueryPerformanceCounter(&c); - current_time = c.QuadPart; -#else -#error Unimplemented Timer::Resume() -#endif - m_StartTime += current_time - m_PauseTime; - m_is_timer_paused = false; -} - -bool Lib::Timer::IsPaused() const { return m_is_timer_paused; } - -double Lib::Timer::GetTimeMsec() const { - if (m_is_timer_paused) { - return 1000.0 * (static_cast(m_PauseTime - m_StartTime)) / static_cast(m_Frequency); - } - - u64 current_time = 0; -#ifdef _WIN64 - LARGE_INTEGER c; - QueryPerformanceCounter(&c); - current_time = c.QuadPart; -#else -#error Unimplemented Timer::GetTimeMsec() -#endif - return 1000.0 * (static_cast(current_time - m_StartTime)) / static_cast(m_Frequency); -} - -double Lib::Timer::GetTimeSec() const { - if (m_is_timer_paused) { - return (static_cast(m_PauseTime - m_StartTime)) / static_cast(m_Frequency); - } - - u64 current_time = 0; -#ifdef _WIN64 - LARGE_INTEGER c; - QueryPerformanceCounter(&c); - current_time = c.QuadPart; -#else -#error Unimplemented Timer::GetTimeSec() -#endif - return (static_cast(current_time - m_StartTime)) / static_cast(m_Frequency); -} - -u64 Lib::Timer::GetTicks() const { - if (m_is_timer_paused) { - return (m_PauseTime - m_StartTime); - } - - u64 current_time = 0; -#ifdef _WIN64 - LARGE_INTEGER c; - QueryPerformanceCounter(&c); - current_time = c.QuadPart; -#else -#error Unimplemented Timer::GetTicks() -#endif - return (current_time - m_StartTime); -} - -u64 Lib::Timer::GetFrequency() const { return m_Frequency; } - diff --git a/src/Lib/Timer.h b/src/Lib/Timer.h deleted file mode 100644 index cdb0cc42..00000000 --- a/src/Lib/Timer.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "../types.h" - -namespace Lib { - class Timer final - { - public: - Timer(); - ~Timer() = default; - - void Start(); - void Pause(); - void Resume(); - bool IsPaused() const; - - double GetTimeMsec() const;// return time in milliseconds - double GetTimeSec() const;// return time in seconds - u64 GetTicks() const;// return time in ticks - u64 GetFrequency() const;// return ticks frequency - - public: - Timer(const Timer&) = delete; - Timer& operator=(const Timer&) = delete; - Timer(Timer&&) = delete; - Timer& operator=(Timer&&) = delete; - - private: - bool m_is_timer_paused = true; - u64 m_Frequency = 0; - u64 m_StartTime = 0; - u64 m_PauseTime = 0; - }; -} \ No newline at end of file