mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-11-23 11:20:07 +00:00
Added Thread class
This commit is contained in:
parent
692759099f
commit
0e1ca354a9
@ -34,6 +34,8 @@ add_executable(shadps4
|
||||
src/Core/Memory.h
|
||||
src/Core/PS4/Linker.cpp
|
||||
src/Core/PS4/Linker.h
|
||||
src/Lib/Threads.cpp
|
||||
src/Lib/Threads.h
|
||||
"src/Util/Singleton.h" "src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Util/StringUtil.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/LibSceVideoOut.cpp" "src/Core/PS4/HLE/LibSceVideoOut.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/MemoryManagement.cpp" "src/Core/PS4/HLE/Kernel/MemoryManagement.h" "src/Core/PS4/HLE/Kernel/MemMngCodes.h" "src/Core/PS4/HLE/Kernel/PhysicalMemory.cpp" "src/Util/StringUtil.cpp")
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
79
src/Lib/Threads.cpp
Normal file
79
src/Lib/Threads.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#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); }
|
125
src/Lib/Threads.h
Normal file
125
src/Lib/Threads.h
Normal file
@ -0,0 +1,125 @@
|
||||
#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;
|
||||
};
|
||||
} // namespace Lib
|
@ -1,113 +1,80 @@
|
||||
#include "Timer.h"
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef _WIN64
|
||||
#include "windows.h"
|
||||
#endif
|
||||
|
||||
Lib::Timer::Timer()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
LARGE_INTEGER f;
|
||||
QueryPerformanceFrequency(&f);
|
||||
m_Frequency = f.QuadPart;
|
||||
#endif
|
||||
Lib::Timer::Timer() {
|
||||
LARGE_INTEGER f;
|
||||
QueryPerformanceFrequency(&f);
|
||||
m_Frequency = f.QuadPart;
|
||||
}
|
||||
|
||||
void Lib::Timer::Start()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
m_StartTime = c.QuadPart;
|
||||
#endif
|
||||
m_is_timer_paused = false;
|
||||
void Lib::Timer::Start() {
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
m_StartTime = c.QuadPart;
|
||||
m_is_timer_paused = false;
|
||||
}
|
||||
|
||||
void Lib::Timer::Pause()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
m_PauseTime = c.QuadPart;
|
||||
#endif
|
||||
m_is_timer_paused = true;
|
||||
void Lib::Timer::Pause() {
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
m_PauseTime = c.QuadPart;
|
||||
m_is_timer_paused = true;
|
||||
}
|
||||
|
||||
void Lib::Timer::Resume()
|
||||
{
|
||||
u64 current_time = 0;
|
||||
void Lib::Timer::Resume() {
|
||||
u64 current_time = 0;
|
||||
|
||||
#ifdef _WIN64
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
current_time = c.QuadPart;
|
||||
#endif
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
current_time = c.QuadPart;
|
||||
|
||||
m_StartTime += current_time - m_PauseTime;
|
||||
m_is_timer_paused = false;
|
||||
m_StartTime += current_time - m_PauseTime;
|
||||
m_is_timer_paused = false;
|
||||
}
|
||||
|
||||
bool Lib::Timer::IsPaused() const
|
||||
{
|
||||
return m_is_timer_paused;
|
||||
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<double>(m_PauseTime - m_StartTime)) / static_cast<double>(m_Frequency);
|
||||
}
|
||||
|
||||
u64 current_time = 0;
|
||||
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
current_time = c.QuadPart;
|
||||
|
||||
return 1000.0 * (static_cast<double>(current_time - m_StartTime)) / static_cast<double>(m_Frequency);
|
||||
}
|
||||
|
||||
double Lib::Timer::GetTimeMsec() const
|
||||
{
|
||||
if (m_is_timer_paused)
|
||||
{
|
||||
return 1000.0 * (static_cast<double>(m_PauseTime - m_StartTime)) / static_cast<double>(m_Frequency);
|
||||
}
|
||||
double Lib::Timer::GetTimeSec() const {
|
||||
if (m_is_timer_paused) {
|
||||
return (static_cast<double>(m_PauseTime - m_StartTime)) / static_cast<double>(m_Frequency);
|
||||
}
|
||||
|
||||
u64 current_time = 0;
|
||||
u64 current_time = 0;
|
||||
|
||||
#ifdef _WIN64
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
current_time = c.QuadPart;
|
||||
#endif
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
current_time = c.QuadPart;
|
||||
|
||||
return 1000.0 * (static_cast<double>(current_time - m_StartTime)) / static_cast<double>(m_Frequency);
|
||||
return (static_cast<double>(current_time - m_StartTime)) / static_cast<double>(m_Frequency);
|
||||
}
|
||||
|
||||
double Lib::Timer::GetTimeSec() const
|
||||
{
|
||||
if (m_is_timer_paused)
|
||||
{
|
||||
return (static_cast<double>(m_PauseTime - m_StartTime)) / static_cast<double>(m_Frequency);
|
||||
}
|
||||
u64 Lib::Timer::GetTicks() const {
|
||||
if (m_is_timer_paused) {
|
||||
return (m_PauseTime - m_StartTime);
|
||||
}
|
||||
|
||||
u64 current_time = 0;
|
||||
u64 current_time = 0;
|
||||
|
||||
#ifdef _WIN64
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
current_time = c.QuadPart;
|
||||
#endif
|
||||
LARGE_INTEGER c;
|
||||
QueryPerformanceCounter(&c);
|
||||
current_time = c.QuadPart;
|
||||
|
||||
return (static_cast<double>(current_time - m_StartTime)) / static_cast<double>(m_Frequency);
|
||||
return (current_time - m_StartTime);
|
||||
}
|
||||
|
||||
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;
|
||||
#endif
|
||||
|
||||
return (current_time - m_StartTime);
|
||||
}
|
||||
|
||||
u64 Lib::Timer::GetFrequency() const
|
||||
{
|
||||
return m_Frequency;
|
||||
}
|
||||
u64 Lib::Timer::GetFrequency() const { return m_Frequency; }
|
||||
|
||||
|
@ -29,17 +29,20 @@
|
||||
#include <inttypes.h>
|
||||
#include <Zydis/Zydis.h>
|
||||
#include "Core/PS4/HLE/Libs.h"
|
||||
#include "Lib/Threads.h"
|
||||
|
||||
// Main code
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
/* if (argc == 1) {
|
||||
if (argc == 1) {
|
||||
printf("Usage: %s <elf or eboot.bin path>\n", argv[0]);
|
||||
return -1;
|
||||
}*/
|
||||
}
|
||||
|
||||
logging::init(true);//init logging
|
||||
const char* const path = argv[1]; // argument 1 is the path of self file to boot
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user