206 lines
6.3 KiB
C++
206 lines
6.3 KiB
C++
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <pthread.h>
|
|
#include <sched.h>
|
|
#include "common/debug.h"
|
|
#include "common/types.h"
|
|
|
|
namespace Core::Loader {
|
|
class SymbolsResolver;
|
|
}
|
|
|
|
namespace Libraries::Kernel {
|
|
constexpr int ORBIS_KERNEL_PRIO_FIFO_DEFAULT = 700;
|
|
constexpr int ORBIS_KERNEL_PRIO_FIFO_HIGHEST = 256;
|
|
constexpr int ORBIS_KERNEL_PRIO_FIFO_LOWEST = 767;
|
|
|
|
struct PthreadInternal;
|
|
struct PthreadAttrInternal;
|
|
struct PthreadMutexInternal;
|
|
struct PthreadMutexattrInternal;
|
|
struct PthreadCondInternal;
|
|
struct PthreadCondAttrInternal;
|
|
struct PthreadRwInternal;
|
|
struct PthreadRwLockAttrInternal;
|
|
class PthreadKeys;
|
|
|
|
using SceKernelSchedParam = ::sched_param;
|
|
using ScePthread = PthreadInternal*;
|
|
using ScePthreadAttr = PthreadAttrInternal*;
|
|
using ScePthreadMutex = PthreadMutexInternal*;
|
|
using ScePthreadMutexattr = PthreadMutexattrInternal*;
|
|
using ScePthreadCond = PthreadCondInternal*;
|
|
using ScePthreadCondattr = PthreadCondAttrInternal*;
|
|
using OrbisPthreadRwlock = PthreadRwInternal*;
|
|
using OrbisPthreadRwlockattr = PthreadRwLockAttrInternal*;
|
|
using OrbisPthreadKey = u32;
|
|
|
|
using PthreadKeyDestructor = PS4_SYSV_ABI void (*)(void*);
|
|
using PthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
|
|
|
|
struct PthreadInternal {
|
|
u8 reserved[4096];
|
|
std::string name;
|
|
pthread_t pth;
|
|
ScePthreadAttr attr;
|
|
PthreadEntryFunc entry;
|
|
void* arg;
|
|
std::atomic_bool is_started;
|
|
std::atomic_bool is_detached;
|
|
std::atomic_bool is_almost_done;
|
|
std::atomic_bool is_free;
|
|
using Destructor = std::pair<OrbisPthreadKey, PthreadKeyDestructor>;
|
|
std::vector<Destructor> key_destructors;
|
|
int prio;
|
|
};
|
|
|
|
struct PthreadAttrInternal {
|
|
u8 reserved[64];
|
|
u64 affinity;
|
|
size_t guard_size;
|
|
int policy;
|
|
bool detached;
|
|
pthread_attr_t pth_attr;
|
|
};
|
|
|
|
struct PthreadMutexInternal {
|
|
u8 reserved[256];
|
|
std::string name;
|
|
pthread_mutex_t pth_mutex;
|
|
std::unique_ptr<tracy::LockableCtx> tracy_lock;
|
|
};
|
|
|
|
struct PthreadMutexattrInternal {
|
|
u8 reserved[64];
|
|
pthread_mutexattr_t pth_mutex_attr;
|
|
int pprotocol;
|
|
};
|
|
|
|
struct PthreadCondInternal {
|
|
u8 reserved[256];
|
|
std::string name;
|
|
pthread_cond_t cond;
|
|
};
|
|
|
|
struct PthreadCondAttrInternal {
|
|
u8 reserved[64];
|
|
pthread_condattr_t cond_attr;
|
|
clockid_t clock;
|
|
};
|
|
|
|
struct PthreadRwLockAttrInternal {
|
|
u8 reserved[64];
|
|
pthread_rwlockattr_t attr_rwlock;
|
|
int type;
|
|
};
|
|
|
|
struct PthreadRwInternal {
|
|
pthread_rwlock_t pth_rwlock;
|
|
std::string name;
|
|
};
|
|
|
|
class PThreadPool {
|
|
public:
|
|
ScePthread Create();
|
|
|
|
private:
|
|
std::vector<ScePthread> m_threads;
|
|
std::mutex m_mutex;
|
|
};
|
|
|
|
class PThreadCxt {
|
|
public:
|
|
ScePthreadMutexattr* getDefaultMutexattr() {
|
|
return &m_default_mutexattr;
|
|
}
|
|
void setDefaultMutexattr(ScePthreadMutexattr attr) {
|
|
m_default_mutexattr = attr;
|
|
}
|
|
ScePthreadCondattr* getDefaultCondattr() {
|
|
return &m_default_condattr;
|
|
}
|
|
void setDefaultCondattr(ScePthreadCondattr attr) {
|
|
m_default_condattr = attr;
|
|
}
|
|
ScePthreadAttr* GetDefaultAttr() {
|
|
return &m_default_attr;
|
|
}
|
|
void SetDefaultAttr(ScePthreadAttr attr) {
|
|
m_default_attr = attr;
|
|
}
|
|
PThreadPool* GetPthreadPool() {
|
|
return m_pthread_pool;
|
|
}
|
|
void SetPthreadPool(PThreadPool* pool) {
|
|
m_pthread_pool = pool;
|
|
}
|
|
OrbisPthreadRwlockattr* getDefaultRwattr() {
|
|
return &m_default_Rwattr;
|
|
}
|
|
void setDefaultRwattr(OrbisPthreadRwlockattr attr) {
|
|
m_default_Rwattr = attr;
|
|
}
|
|
|
|
private:
|
|
ScePthreadMutexattr m_default_mutexattr = nullptr;
|
|
ScePthreadCondattr m_default_condattr = nullptr;
|
|
ScePthreadAttr m_default_attr = nullptr;
|
|
PThreadPool* m_pthread_pool = nullptr;
|
|
OrbisPthreadRwlockattr m_default_Rwattr = nullptr;
|
|
};
|
|
|
|
void init_pthreads();
|
|
void pthreadInitSelfMainThread();
|
|
|
|
int PS4_SYSV_ABI scePthreadAttrInit(ScePthreadAttr* attr);
|
|
int PS4_SYSV_ABI scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachstate);
|
|
int PS4_SYSV_ABI scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inheritSched);
|
|
int PS4_SYSV_ABI scePthreadAttrSetschedparam(ScePthreadAttr* attr,
|
|
const SceKernelSchedParam* param);
|
|
int PS4_SYSV_ABI scePthreadAttrSetschedpolicy(ScePthreadAttr* attr, int policy);
|
|
ScePthread PS4_SYSV_ABI scePthreadSelf();
|
|
int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr,
|
|
const /*SceKernelCpumask*/ u64 mask);
|
|
int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpumask*/ u64 mask);
|
|
int PS4_SYSV_ABI scePthreadGetaffinity(ScePthread thread, /*SceKernelCpumask*/ u64* mask);
|
|
int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr,
|
|
PthreadEntryFunc start_routine, void* arg, const char* name);
|
|
|
|
int PS4_SYSV_ABI scePthreadSetprio(ScePthread thread, int prio);
|
|
|
|
/***
|
|
* Mutex calls
|
|
*/
|
|
int PS4_SYSV_ABI scePthreadMutexInit(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr,
|
|
const char* name);
|
|
int PS4_SYSV_ABI scePthreadMutexattrInit(ScePthreadMutexattr* attr);
|
|
int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type);
|
|
int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol);
|
|
int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex);
|
|
int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex);
|
|
/****
|
|
* Cond calls
|
|
*/
|
|
int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondattr* attr,
|
|
const char* name);
|
|
int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr);
|
|
int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond);
|
|
int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex);
|
|
/****
|
|
* Posix calls
|
|
*/
|
|
int PS4_SYSV_ABI posix_pthread_mutex_init(ScePthreadMutex* mutex, const ScePthreadMutexattr* attr);
|
|
int PS4_SYSV_ABI posix_pthread_mutex_lock(ScePthreadMutex* mutex);
|
|
int PS4_SYSV_ABI posix_pthread_mutex_unlock(ScePthreadMutex* mutex);
|
|
int PS4_SYSV_ABI posix_pthread_cond_broadcast(ScePthreadCond* cond);
|
|
|
|
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
|
} // namespace Libraries::Kernel
|