114 lines
2.9 KiB
C++
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());
|
|
}
|
|
} |