diff --git a/projects/clr/rocclr/runtime/os/os_posix.cpp b/projects/clr/rocclr/runtime/os/os_posix.cpp index 9b7e33e317..3617d36d05 100644 --- a/projects/clr/rocclr/runtime/os/os_posix.cpp +++ b/projects/clr/rocclr/runtime/os/os_posix.cpp @@ -394,6 +394,36 @@ bool Os::isThreadAlive(const Thread& thread) { return ::pthread_kill((pthread_t)thread.handle(), 0) == 0; } +static size_t tlsSize = 0; + +// Try to guess the size of TLS (plus some frames) +void* guessTlsSizeThread(void* param) { + address stackBase; + address currentFrame; + size_t stackSize; + Os::currentStackInfo(&stackBase, &stackSize); + currentFrame = reinterpret_cast
(&stackSize); + tlsSize = stackBase - currentFrame; + // align up to page boundary + tlsSize = alignUp(tlsSize, amd::Os::pageSize()); + return NULL; +} + +static void guessTlsSize(void) { + int retval; + pthread_t handle; + pthread_attr_t threadAttr; + + ::pthread_attr_init(&threadAttr); + retval = ::pthread_create(&handle, &threadAttr, guessTlsSizeThread, NULL); + if (retval == 0) { + pthread_join(handle, NULL); + } else { + fatal("pthread_create() failed with default stack size"); + } + ::pthread_attr_destroy(&threadAttr); +} + const void* Os::createOsThread(amd::Thread* thread) { pthread_attr_t threadAttr; ::pthread_attr_init(&threadAttr); @@ -403,7 +433,10 @@ const void* Os::createOsThread(amd::Thread* thread) { if (0 != ::pthread_attr_getguardsize(&threadAttr, &guardsize)) { fatal("pthread_attr_getguardsize() failed"); } - ::pthread_attr_setstacksize(&threadAttr, thread->stackSize_ + guardsize); + + static std::once_flag initOnce; + std::call_once(initOnce, guessTlsSize); + ::pthread_attr_setstacksize(&threadAttr, thread->stackSize_ + guardsize + tlsSize); } // We never plan the use join, so free the resources now.