AuroraRuntime/Source/Threading/Threads/ThreadHandles.cpp

114 lines
2.9 KiB
C++

/***
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: ThreadHandles.cpp
Date: 2021-6-19
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "Threads.hpp"
#include "ThreadHandles.hpp"
#include "OSThread.hpp"
namespace Aurora::Threading::Threads
{
static IAuroraThread *OsThreadAnnounce(AuUInt64 threadId);
static void OsThreadShutdown(AuUInt64 threadId);
static AuUInt64 GetThreadIdHandle()
{
#if defined(AURORA_IS_MODERNNT_DERIVED)
// Note: The OsThreadAnnounce function takes ownership of win32 handles.
// The detor of OSThread is responsible for cleaning up this handle.
HANDLE ret;
auto process = GetCurrentProcess();
auto thread = GetCurrentProcess();
if (!DuplicateHandle(process, thread, process, &ret, DUPLICATE_SAME_ACCESS, FALSE, DUPLICATE_SAME_ACCESS))
{
return reinterpret_cast<AuUInt64>(INVALID_HANDLE_VALUE);
}
return reinterpret_cast<AuUInt64>(ret);
#elif defined(AURORA_HAS_PTHREADS)
return pthread_self();
#endif
}
struct OSFallbackThread
{
AuUInt64 threadId;
IAuroraThread *handle;
OSFallbackThread()
{
threadId = GetThreadIdHandle();
handle = OsThreadAnnounce(threadId);
}
~OSFallbackThread()
{
OsThreadShutdown(threadId);
}
};
#if defined(AURORA_COMPILER_MSVC)
#define DEFINE_SPEEDY_TLS(type, name) static thread_local type name;
#elif defined(AURORA_COMPILER_CLANG) || defined(AURORA_COMPILER_GCC)
#define DEFINE_SPEEDY_TLS(type, name) __thread type name __attribute__((tls_model("initial-exec")));
#else
#define DEFINE_SPEEDY_TLS(type, name) static thread_local type name;
#endif
DEFINE_SPEEDY_TLS(OSFallbackThread, tlsOsFallbackThread);
DEFINE_SPEEDY_TLS(IAuroraThread*, tlsCurrentThread);
void HandleRemove()
{
tlsCurrentThread = nullptr;
}
void HandleRegister(IAuroraThread *thread)
{
tlsCurrentThread = thread;
}
IAuroraThread *HandleCurrent()
{
return tlsCurrentThread;
}
IAuroraThread *OsThreadAnnounce(AuUInt64 threadId)
{
SysAssertDbg(tlsOsFallbackThread.threadId == threadId);
return _new OSThread(threadId);
}
void OsThreadShutdown(AuUInt64 threadId)
{
SysAssertDbg(tlsOsFallbackThread.threadId == threadId);
SafeDelete<OSThread *>(tlsOsFallbackThread.handle);
}
AUKN_SYM IAuroraThread *GetThread()
{
auto ret = tlsCurrentThread;
if (ret)
{
return ret;
}
ret = tlsOsFallbackThread.handle;
if (ret)
{
return ret;
}
SysPanic("no tls context");
}
AUKN_SYM AuThreadId_t GetThreadId()
{
return reinterpret_cast<AuThreadId_t>(GetThread());
}
}