2024-02-27 22:10:34 +00:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
2024-07-14 04:38:20 +00:00
|
|
|
#include <mutex>
|
2024-02-27 22:10:34 +00:00
|
|
|
#include "common/assert.h"
|
|
|
|
#include "common/types.h"
|
|
|
|
#include "core/tls.h"
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include <windows.h>
|
2024-07-14 04:38:20 +00:00
|
|
|
#elif defined(__APPLE__)
|
|
|
|
#include <pthread.h>
|
2024-02-27 22:10:34 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace Core {
|
|
|
|
|
2024-05-01 10:38:41 +00:00
|
|
|
#ifdef _WIN32
|
2024-07-14 04:38:20 +00:00
|
|
|
|
2024-05-01 10:38:41 +00:00
|
|
|
static DWORD slot = 0;
|
2024-02-27 22:10:34 +00:00
|
|
|
|
2024-07-14 04:38:20 +00:00
|
|
|
static void AllocTcbKey() {
|
|
|
|
slot = TlsAlloc();
|
|
|
|
}
|
|
|
|
|
2024-06-05 19:08:18 +00:00
|
|
|
void SetTcbBase(void* image_address) {
|
2024-07-14 04:38:20 +00:00
|
|
|
const BOOL result = TlsSetValue(GetTcbKey(), image_address);
|
2024-05-01 10:38:41 +00:00
|
|
|
ASSERT(result != 0);
|
2024-02-27 22:10:34 +00:00
|
|
|
}
|
|
|
|
|
2024-06-05 19:08:18 +00:00
|
|
|
Tcb* GetTcbBase() {
|
2024-07-14 04:38:20 +00:00
|
|
|
return reinterpret_cast<Tcb*>(TlsGetValue(GetTcbKey()));
|
2024-06-13 21:58:57 +00:00
|
|
|
}
|
|
|
|
|
2024-07-09 09:18:34 +00:00
|
|
|
#elif defined(__APPLE__)
|
|
|
|
|
|
|
|
static pthread_key_t slot = 0;
|
|
|
|
|
|
|
|
static void AllocTcbKey() {
|
|
|
|
ASSERT(pthread_key_create(&slot, nullptr) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetTcbBase(void* image_address) {
|
2024-07-14 04:38:20 +00:00
|
|
|
ASSERT(pthread_setspecific(GetTcbKey(), image_address) == 0);
|
2024-07-09 09:18:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Tcb* GetTcbBase() {
|
2024-07-14 04:38:20 +00:00
|
|
|
return reinterpret_cast<Tcb*>(pthread_getspecific(GetTcbKey()));
|
2024-07-09 09:18:34 +00:00
|
|
|
}
|
|
|
|
|
2024-06-13 21:58:57 +00:00
|
|
|
#else
|
|
|
|
|
2024-07-14 04:38:20 +00:00
|
|
|
// Placeholder for code compatibility.
|
|
|
|
static constexpr u32 slot = 0;
|
|
|
|
|
|
|
|
static void AllocTcbKey() {}
|
2024-06-13 21:58:57 +00:00
|
|
|
|
|
|
|
void SetTcbBase(void* image_address) {
|
2024-07-15 00:47:10 +00:00
|
|
|
asm volatile("wrgsbase %0" ::"r"(image_address) : "memory");
|
2024-06-13 21:58:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Tcb* GetTcbBase() {
|
2024-07-14 22:48:57 +00:00
|
|
|
Tcb* tcb;
|
2024-07-15 00:47:10 +00:00
|
|
|
asm volatile("rdgsbase %0" : "=r"(tcb)::"memory");
|
2024-07-14 22:48:57 +00:00
|
|
|
return tcb;
|
2024-06-13 21:58:57 +00:00
|
|
|
}
|
2024-02-27 22:10:34 +00:00
|
|
|
|
2024-06-13 21:58:57 +00:00
|
|
|
#endif
|
|
|
|
|
2024-07-14 04:38:20 +00:00
|
|
|
static std::once_flag slot_alloc_flag;
|
|
|
|
|
|
|
|
u32 GetTcbKey() {
|
|
|
|
std::call_once(slot_alloc_flag, &AllocTcbKey);
|
|
|
|
return slot;
|
2024-02-27 22:10:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Core
|