core: Switch to std threading primitives
This commit is contained in:
parent
f39744cf62
commit
e2b1b059ed
|
@ -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
|
||||
|
|
|
@ -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<GPUMemory>::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<GPUMemory>::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) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <Core/PS4/HLE/Graphics/graphics_ctx.h>
|
||||
#include <types.h>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
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<MemoryHeap> 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);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "tile_manager.h"
|
||||
#include "Lib/Threads.h"
|
||||
#include "Emulator/Util/singleton.h"
|
||||
#include <mutex>
|
||||
|
||||
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<TileManager>::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;
|
||||
|
|
|
@ -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<int>(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<void*>(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<void*>(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<int>(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<int>(m_requests.size());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}; // namespace HLE::Graphics::Objects
|
||||
}; // namespace HLE::Graphics::Objects
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <Core/PS4/HLE/Graphics/video_out.h>
|
||||
#include <Lib/Threads.h>
|
||||
#include <Core/PS4/HLE/Graphics/graphics_ctx.h>
|
||||
#include <emulator.h>
|
||||
|
||||
|
@ -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<Request> 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;
|
||||
|
|
|
@ -2,13 +2,12 @@
|
|||
|
||||
#include <types.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "Lib/Threads.h"
|
||||
#include <mutex>
|
||||
|
||||
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<u32>(-1);
|
||||
u32 index = static_cast<u32>(-1);
|
||||
VkQueue vk_queue = nullptr;
|
||||
|
|
|
@ -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<RenderCtx>::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<RenderCtx>::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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<uint32_t>(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) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
#include <Lib/Threads.h>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -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<EqueueEvent> m_events;
|
||||
Lib::ConditionVariable m_cond;
|
||||
std::condition_variable m_cond;
|
||||
};
|
||||
}; // namespace HLE::Kernel::Objects
|
|
@ -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) {
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#include <types.h>
|
||||
#include <Core/virtual_memory.h>
|
||||
#include <Core/PS4/GPU/gpu_memory.h>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include "Lib/Threads.h"
|
||||
|
||||
namespace HLE::Kernel::Objects {
|
||||
|
||||
|
@ -28,7 +28,7 @@ class PhysicalMemory {
|
|||
|
||||
private:
|
||||
std::vector<AllocatedBlock> m_allocatedBlocks;
|
||||
Lib::Mutex m_mutex;
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
|
||||
} // namespace HLE::Kernel::Objects
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <Util/log.h>
|
||||
#include <debug.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "Emulator/Util/singleton.h"
|
||||
#include "../Loader/Elf.h"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include "Loader/Elf.h"
|
||||
#include "Loader/SymbolsResolver.h"
|
||||
#include "Lib/Threads.h"
|
||||
|
||||
struct DynamicModuleInfo;
|
||||
class Linker;
|
||||
|
@ -130,5 +130,5 @@ public:
|
|||
|
||||
std::vector<Module*> m_modules;
|
||||
SymbolsResolver* m_HLEsymbols = nullptr;
|
||||
Lib::Mutex m_mutex;
|
||||
std::mutex m_mutex;
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include <types.h>
|
||||
#include "Lib/Threads.h"
|
||||
#include <mutex>
|
||||
|
||||
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;
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
#include "Threads.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
static std::thread::id g_main_thread;
|
||||
static int g_main_thread_int;
|
||||
static std::atomic<int> 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); }
|
|
@ -1,131 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "windows.h"
|
||||
#include <synchapi.h>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#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
|
|
@ -22,10 +22,10 @@ void emuInit(u32 width, u32 height) {
|
|||
|
||||
void checkAndWaitForGraphicsInit() {
|
||||
auto* window_ctx = singleton<Emu::WindowCtx>::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<Emu::WindowCtx>::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<Emu::WindowCtx>::instance();
|
||||
Lib::LockMutexGuard lock(window_ctx->m_mutex);
|
||||
|
||||
std::scoped_lock lock{window_ctx->m_mutex};
|
||||
return &window_ctx->m_graphic_ctx;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <Core/PS4/HLE/Graphics/graphics_ctx.h>
|
||||
#include <Lib/Threads.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <vector>
|
||||
|
||||
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;
|
||||
|
|
|
@ -31,10 +31,10 @@
|
|||
#include <emulator.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <thread>
|
||||
|
||||
#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<Linker>::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<Linker>::instance();
|
||||
linker->Execute();
|
||||
},
|
||||
nullptr);
|
||||
mainthread.DetachThread();
|
||||
Discord::RPC discordRPC;
|
||||
discordRPC.init();
|
||||
discordRPC.update(Discord::RPCStatus::Idling, "");
|
||||
Emu::emuRun();
|
||||
mainthread.JoinThread();
|
||||
|
||||
#if 0
|
||||
// Setup SDL
|
||||
|
|
|
@ -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<Emu::WindowCtx>::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;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue