Adding TLS abstraction.
This commit is contained in:
parent
48d5d76882
commit
c3415e6332
|
@ -89,6 +89,14 @@ SleepResult AlertableSleep(std::chrono::duration<Rep, Period> duration) {
|
||||||
std::chrono::duration_cast<std::chrono::microseconds>(duration));
|
std::chrono::duration_cast<std::chrono::microseconds>(duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef uint32_t TlsHandle;
|
||||||
|
constexpr TlsHandle kInvalidTlsHandle = UINT_MAX;
|
||||||
|
|
||||||
|
TlsHandle AllocateTlsHandle();
|
||||||
|
bool FreeTlsHandle(TlsHandle handle);
|
||||||
|
uintptr_t GetTlsValue(TlsHandle handle);
|
||||||
|
bool SetTlsValue(TlsHandle handle, uintptr_t value);
|
||||||
|
|
||||||
// Results for a WaitHandle operation.
|
// Results for a WaitHandle operation.
|
||||||
enum class WaitResult {
|
enum class WaitResult {
|
||||||
// The state of the specified object is signaled.
|
// The state of the specified object is signaled.
|
||||||
|
|
|
@ -96,6 +96,18 @@ SleepResult AlertableSleep(std::chrono::microseconds duration) {
|
||||||
return SleepResult::kSuccess;
|
return SleepResult::kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TlsHandle AllocateTlsHandle() { return TlsAlloc(); }
|
||||||
|
|
||||||
|
bool FreeTlsHandle(TlsHandle handle) { return TlsFree(handle) ? true : false; }
|
||||||
|
|
||||||
|
uintptr_t GetTlsValue(TlsHandle handle) {
|
||||||
|
return reinterpret_cast<uintptr_t>(TlsGetValue(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetTlsValue(TlsHandle handle, uintptr_t value) {
|
||||||
|
return TlsSetValue(handle, reinterpret_cast<void*>(value)) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Win32Handle : public T {
|
class Win32Handle : public T {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/mutex.h"
|
#include "xenia/base/mutex.h"
|
||||||
#include "xenia/base/platform_win.h"
|
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/kernel/dispatcher.h"
|
#include "xenia/kernel/dispatcher.h"
|
||||||
#include "xenia/kernel/kernel_state.h"
|
#include "xenia/kernel/kernel_state.h"
|
||||||
|
@ -371,18 +370,10 @@ SHIM_CALL KeQuerySystemTime_shim(PPCContext* ppc_context,
|
||||||
SHIM_CALL KeTlsAlloc_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
SHIM_CALL KeTlsAlloc_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||||
XELOGD("KeTlsAlloc()");
|
XELOGD("KeTlsAlloc()");
|
||||||
|
|
||||||
uint32_t tls_index;
|
auto tls_index = xe::threading::AllocateTlsHandle();
|
||||||
|
if (tls_index == xe::threading::kInvalidTlsHandle) {
|
||||||
#if XE_PLATFORM_WIN32
|
|
||||||
tls_index = TlsAlloc();
|
|
||||||
#else
|
|
||||||
pthread_key_t key;
|
|
||||||
if (pthread_key_create(&key, NULL)) {
|
|
||||||
tls_index = X_TLS_OUT_OF_INDEXES;
|
tls_index = X_TLS_OUT_OF_INDEXES;
|
||||||
} else {
|
|
||||||
tls_index = (uint32_t)key;
|
|
||||||
}
|
}
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(tls_index);
|
SHIM_SET_RETURN_32(tls_index);
|
||||||
}
|
}
|
||||||
|
@ -398,14 +389,7 @@ SHIM_CALL KeTlsFree_shim(PPCContext* ppc_context, KernelState* kernel_state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = 0;
|
uint32_t result = xe::threading::FreeTlsHandle(tls_index) ? 1 : 0;
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
|
||||||
result = TlsFree(tls_index);
|
|
||||||
#else
|
|
||||||
result = pthread_key_delete(tls_index) == 0;
|
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(result);
|
SHIM_SET_RETURN_32(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,17 +403,10 @@ SHIM_CALL KeTlsGetValue_shim(PPCContext* ppc_context,
|
||||||
// "KeTlsGetValue(%.8X)",
|
// "KeTlsGetValue(%.8X)",
|
||||||
// tls_index);
|
// tls_index);
|
||||||
|
|
||||||
uint64_t value = 0;
|
uint32_t value = static_cast<uint32_t>(xe::threading::GetTlsValue(tls_index));
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
|
||||||
value = (uint64_t)TlsGetValue(tls_index);
|
|
||||||
#else
|
|
||||||
value = (uint64_t)pthread_getspecific(tls_index);
|
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
// XELOGW("KeTlsGetValue should SetLastError if result is NULL");
|
// XELOGW("KeTlsGetValue should SetLastError if result is NULL");
|
||||||
// TODO(benvanik): SetLastError
|
// TODO(benvanik): SetLastError? Or does user code do this?
|
||||||
}
|
}
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(value);
|
SHIM_SET_RETURN_32(value);
|
||||||
|
@ -443,15 +420,7 @@ SHIM_CALL KeTlsSetValue_shim(PPCContext* ppc_context,
|
||||||
|
|
||||||
XELOGD("KeTlsSetValue(%.8X, %.8X)", tls_index, tls_value);
|
XELOGD("KeTlsSetValue(%.8X, %.8X)", tls_index, tls_value);
|
||||||
|
|
||||||
int result = 0;
|
uint32_t result = xe::threading::SetTlsValue(tls_index, tls_value) ? 1 : 0;
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
|
||||||
result = TlsSetValue(
|
|
||||||
tls_index, reinterpret_cast<void*>(static_cast<uintptr_t>(tls_value)));
|
|
||||||
#else
|
|
||||||
result = pthread_setspecific(tls_index, (void*)tls_value) == 0;
|
|
||||||
#endif // WIN32
|
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(result);
|
SHIM_SET_RETURN_32(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue