diff options
Diffstat (limited to '3rdparty/bx/src/thread.cpp')
-rw-r--r-- | 3rdparty/bx/src/thread.cpp | 156 |
1 files changed, 95 insertions, 61 deletions
diff --git a/3rdparty/bx/src/thread.cpp b/3rdparty/bx/src/thread.cpp index f52e0bdcbf4..f5e5f81bc21 100644 --- a/3rdparty/bx/src/thread.cpp +++ b/3rdparty/bx/src/thread.cpp @@ -1,39 +1,45 @@ /* - * Copyright 2010-2018 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bx#license-bsd-2-clause + * Copyright 2010-2022 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bx/blob/master/LICENSE */ -#include "bx_p.h" +#include <bx/os.h> #include <bx/thread.h> #if BX_CONFIG_SUPPORTS_THREADING +#if BX_PLATFORM_WINDOWS && !BX_CRT_NONE +# include <bx/string.h> +#endif + #if BX_CRT_NONE # include "crt0.h" #elif BX_PLATFORM_ANDROID \ + || BX_PLATFORM_BSD \ + || BX_PLATFORM_HAIKU \ || BX_PLATFORM_LINUX \ || BX_PLATFORM_IOS \ || BX_PLATFORM_OSX \ || BX_PLATFORM_PS4 \ - || BX_PLATFORM_RPI + || BX_PLATFORM_RPI \ + || BX_PLATFORM_NX # include <pthread.h> -# if defined(__FreeBSD__) +# if BX_PLATFORM_BSD # include <pthread_np.h> -# endif +# endif // BX_PLATFORM_BSD # if BX_PLATFORM_LINUX && (BX_CRT_GLIBC < 21200) # include <sys/prctl.h> # endif // BX_PLATFORM_ #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ - || BX_PLATFORM_XBOXONE + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif // WIN32_LEAN_AND_MEAN # include <windows.h> # include <limits.h> # include <errno.h> -# if BX_PLATFORM_WINRT -using namespace Platform; -using namespace Windows::Foundation; -using namespace Windows::System::Threading; -# endif // BX_PLATFORM_WINRT #endif // BX_PLATFORM_ namespace bx @@ -122,20 +128,25 @@ namespace bx } } - void Thread::init(ThreadFn _fn, void* _userData, uint32_t _stackSize, const char* _name) + bool Thread::init(ThreadFn _fn, void* _userData, uint32_t _stackSize, const char* _name) { - BX_CHECK(!m_running, "Already running!"); + BX_ASSERT(!m_running, "Already running!"); m_fn = _fn; m_userData = _userData; m_stackSize = _stackSize; - m_running = true; ThreadInternal* ti = (ThreadInternal*)m_internal; #if BX_CRT_NONE ti->m_handle = crt0::threadCreate(&ti->threadFunc, _userData, m_stackSize, _name); + + if (NULL == ti->m_handle) + { + return false; + } #elif BX_PLATFORM_WINDOWS \ - || BX_PLATFORM_XBOXONE + || BX_PLATFORM_XBOXONE \ + || BX_PLATFORM_WINRT ti->m_handle = ::CreateThread(NULL , m_stackSize , (LPTHREAD_START_ROUTINE)ti->threadFunc @@ -143,48 +154,57 @@ namespace bx , 0 , NULL ); -#elif BX_PLATFORM_WINRT - ti->m_handle = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); - auto workItemHandler = ref new WorkItemHandler([=](IAsyncAction^) - { - m_exitCode = ti->threadFunc(this); - SetEvent(ti->m_handle); - } - , CallbackContext::Any - ); - - ThreadPool::RunAsync(workItemHandler, WorkItemPriority::Normal, WorkItemOptions::TimeSliced); + if (NULL == ti->m_handle) + { + return false; + } #elif BX_PLATFORM_POSIX int result; BX_UNUSED(result); pthread_attr_t attr; result = pthread_attr_init(&attr); - BX_CHECK(0 == result, "pthread_attr_init failed! %d", result); + BX_WARN(0 == result, "pthread_attr_init failed! %d", result); + if (0 != result) + { + return false; + } if (0 != m_stackSize) { result = pthread_attr_setstacksize(&attr, m_stackSize); - BX_CHECK(0 == result, "pthread_attr_setstacksize failed! %d", result); + BX_WARN(0 == result, "pthread_attr_setstacksize failed! %d", result); + + if (0 != result) + { + return false; + } } result = pthread_create(&ti->m_handle, &attr, &ti->threadFunc, this); - BX_CHECK(0 == result, "pthread_attr_setschedparam failed! %d", result); + BX_WARN(0 == result, "pthread_attr_setschedparam failed! %d", result); + if (0 != result) + { + return false; + } #else # error "Not implemented!" #endif // BX_PLATFORM_ + m_running = true; m_sem.wait(); if (NULL != _name) { setThreadName(_name); } + + return true; } void Thread::shutdown() { - BX_CHECK(m_running, "Not running!"); + BX_ASSERT(m_running, "Not running!"); ThreadInternal* ti = (ThreadInternal*)m_internal; #if BX_CRT_NONE crt0::threadJoin(ti->m_handle, NULL); @@ -240,33 +260,47 @@ namespace bx # else pthread_set_name_np(ti->m_handle, _name); # endif // defined(__NetBSD__) -#elif BX_PLATFORM_WINDOWS && BX_COMPILER_MSVC -# pragma pack(push, 8) - struct ThreadName - { - DWORD type; - LPCSTR name; - DWORD id; - DWORD flags; - }; -# pragma pack(pop) - ThreadName tn; - tn.type = 0x1000; - tn.name = _name; - tn.id = ti->m_threadId; - tn.flags = 0; - - __try - { - RaiseException(0x406d1388 - , 0 - , sizeof(tn)/4 - , reinterpret_cast<ULONG_PTR*>(&tn) - ); - } - __except(EXCEPTION_EXECUTE_HANDLER) +#elif BX_PLATFORM_WINDOWS + // Try to use the new thread naming API from Win10 Creators update onwards if we have it + typedef HRESULT (WINAPI *SetThreadDescriptionProc)(HANDLE, PCWSTR); + SetThreadDescriptionProc SetThreadDescription = dlsym<SetThreadDescriptionProc>((void*)GetModuleHandleA("Kernel32.dll"), "SetThreadDescription"); + + if (NULL != SetThreadDescription) { + uint32_t length = (uint32_t)strLen(_name)+1; + uint32_t size = length*sizeof(wchar_t); + wchar_t* name = (wchar_t*)alloca(size); + mbstowcs(name, _name, size-2); + SetThreadDescription(ti->m_handle, name); } +# if BX_COMPILER_MSVC +# pragma pack(push, 8) + struct ThreadName + { + DWORD type; + LPCSTR name; + DWORD id; + DWORD flags; + }; +# pragma pack(pop) + ThreadName tn; + tn.type = 0x1000; + tn.name = _name; + tn.id = ti->m_threadId; + tn.flags = 0; + + __try + { + RaiseException(0x406d1388 + , 0 + , sizeof(tn)/4 + , reinterpret_cast<ULONG_PTR*>(&tn) + ); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } +# endif // BX_COMPILER_MSVC #else BX_UNUSED(_name); #endif // BX_PLATFORM_ @@ -339,14 +373,14 @@ namespace bx TlsDataInternal* ti = (TlsDataInternal*)m_internal; ti->m_id = TlsAlloc(); - BX_CHECK(TLS_OUT_OF_INDEXES != ti->m_id, "Failed to allocated TLS index (err: 0x%08x).", GetLastError() ); + BX_ASSERT(TLS_OUT_OF_INDEXES != ti->m_id, "Failed to allocated TLS index (err: 0x%08x).", GetLastError() ); } TlsData::~TlsData() { TlsDataInternal* ti = (TlsDataInternal*)m_internal; BOOL result = TlsFree(ti->m_id); - BX_CHECK(0 != result, "Failed to free TLS index (err: 0x%08x).", GetLastError() ); BX_UNUSED(result); + BX_ASSERT(0 != result, "Failed to free TLS index (err: 0x%08x).", GetLastError() ); BX_UNUSED(result); } void* TlsData::get() const @@ -369,14 +403,14 @@ namespace bx TlsDataInternal* ti = (TlsDataInternal*)m_internal; int result = pthread_key_create(&ti->m_id, NULL); - BX_CHECK(0 == result, "pthread_key_create failed %d.", result); BX_UNUSED(result); + BX_ASSERT(0 == result, "pthread_key_create failed %d.", result); BX_UNUSED(result); } TlsData::~TlsData() { TlsDataInternal* ti = (TlsDataInternal*)m_internal; int result = pthread_key_delete(ti->m_id); - BX_CHECK(0 == result, "pthread_key_delete failed %d.", result); BX_UNUSED(result); + BX_ASSERT(0 == result, "pthread_key_delete failed %d.", result); BX_UNUSED(result); } void* TlsData::get() const @@ -389,7 +423,7 @@ namespace bx { TlsDataInternal* ti = (TlsDataInternal*)m_internal; int result = pthread_setspecific(ti->m_id, _ptr); - BX_CHECK(0 == result, "pthread_setspecific failed %d.", result); BX_UNUSED(result); + BX_ASSERT(0 == result, "pthread_setspecific failed %d.", result); BX_UNUSED(result); } #endif // BX_PLATFORM_* |