shadPS4/src/core/tls.cpp

77 lines
1.4 KiB
C++
Raw Normal View History

// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <mutex>
#include "common/assert.h"
#include "common/types.h"
#include "core/tls.h"
#ifdef _WIN32
#include <windows.h>
#elif defined(__APPLE__)
#include <pthread.h>
#endif
namespace Core {
#ifdef _WIN32
static DWORD slot = 0;
static void AllocTcbKey() {
slot = TlsAlloc();
}
void SetTcbBase(void* image_address) {
const BOOL result = TlsSetValue(GetTcbKey(), image_address);
ASSERT(result != 0);
}
Tcb* GetTcbBase() {
return reinterpret_cast<Tcb*>(TlsGetValue(GetTcbKey()));
}
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) {
ASSERT(pthread_setspecific(GetTcbKey(), image_address) == 0);
2024-07-09 09:18:34 +00:00
}
Tcb* GetTcbBase() {
return reinterpret_cast<Tcb*>(pthread_getspecific(GetTcbKey()));
2024-07-09 09:18:34 +00:00
}
#else
// Placeholder for code compatibility.
static constexpr u32 slot = 0;
static void AllocTcbKey() {}
void SetTcbBase(void* image_address) {
2024-07-15 00:47:10 +00:00
asm volatile("wrgsbase %0" ::"r"(image_address) : "memory");
}
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;
}
#endif
static std::once_flag slot_alloc_flag;
u32 GetTcbKey() {
std::call_once(slot_alloc_flag, &AllocTcbKey);
return slot;
}
} // namespace Core