diff --git a/runtime/vm/os_thread.cc b/runtime/vm/os_thread.cc index 5b62d16ec51..125dabf6d45 100644 --- a/runtime/vm/os_thread.cc +++ b/runtime/vm/os_thread.cc @@ -19,6 +19,10 @@ OSThread* OSThread::thread_list_head_ = NULL; Mutex* OSThread::thread_list_lock_ = NULL; bool OSThread::creation_enabled_ = false; +#if defined(HAS_C11_THREAD_LOCAL) +thread_local Thread* OSThread::current_vm_thread_ = NULL; +#endif + OSThread::OSThread() : BaseThread(true), id_(OSThread::GetCurrentThreadId()), @@ -269,8 +273,18 @@ void OSThread::RemoveThreadFromList(OSThread* thread) { } } -void OSThread::SetCurrent(OSThread* current) { - OSThread::SetThreadLocal(thread_key_, reinterpret_cast(current)); +void OSThread::SetCurrentTLS(BaseThread* value) { + // Provides thread-local destructors. + SetThreadLocal(thread_key_, reinterpret_cast(value)); + +#if defined(HAS_C11_THREAD_LOCAL) + // Allows the C compiler more freedom to optimize. + if ((value != NULL) && !value->is_os_thread()) { + current_vm_thread_ = static_cast(value); + } else { + current_vm_thread_ = NULL; + } +#endif } OSThreadIterator::OSThreadIterator() { diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h index cdf39855be3..baad4af32c5 100644 --- a/runtime/vm/os_thread.h +++ b/runtime/vm/os_thread.h @@ -11,6 +11,10 @@ #include "vm/allocation.h" #include "vm/globals.h" +#if !HOST_OS_IOS +#define HAS_C11_THREAD_LOCAL 1 +#endif + // Declare the OS-specific types ahead of defining the generic classes. #if defined(HOST_OS_ANDROID) #include "vm/os_thread_android.h" @@ -154,7 +158,11 @@ class OSThread : public BaseThread { } return os_thread; } - static void SetCurrent(OSThread* current); + static void SetCurrent(OSThread* current) { SetCurrentTLS(current); } + +#if defined(HAS_C11_THREAD_LOCAL) + static Thread* CurrentVMThread() { return current_vm_thread_; } +#endif // TODO(5411455): Use flag to override default value and Validate the // stack size by querying OS. @@ -166,7 +174,7 @@ class OSThread : public BaseThread { static BaseThread* GetCurrentTLS() { return reinterpret_cast(OSThread::GetThreadLocal(thread_key_)); } - static void SetCurrentTLS(uword value) { SetThreadLocal(thread_key_, value); } + static void SetCurrentTLS(BaseThread* value); typedef void (*ThreadStartFunction)(uword parameter); typedef void (*ThreadDestructor)(void* parameter); @@ -265,6 +273,10 @@ class OSThread : public BaseThread { static OSThread* thread_list_head_; static bool creation_enabled_; +#if defined(HAS_C11_THREAD_LOCAL) + static thread_local Thread* current_vm_thread_; +#endif + friend class Isolate; // to access set_thread(Thread*). friend class OSThreadIterator; friend class ThreadInterrupterWin; diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h index 8864071abed..f63f2aae3d2 100644 --- a/runtime/vm/thread.h +++ b/runtime/vm/thread.h @@ -212,11 +212,15 @@ class Thread : public BaseThread { // The currently executing thread, or NULL if not yet initialized. static Thread* Current() { +#if defined(HAS_C11_THREAD_LOCAL) + return OSThread::CurrentVMThread(); +#else BaseThread* thread = OSThread::GetCurrentTLS(); if (thread == NULL || thread->is_os_thread()) { return NULL; } return reinterpret_cast(thread); +#endif } // Makes the current thread enter 'isolate'. @@ -902,9 +906,7 @@ class Thread : public BaseThread { void ExitSafepointUsingLock(); void BlockForSafepoint(); - static void SetCurrent(Thread* current) { - OSThread::SetCurrentTLS(reinterpret_cast(current)); - } + static void SetCurrent(Thread* current) { OSThread::SetCurrentTLS(current); } void DeferOOBMessageInterrupts(); void RestoreOOBMessageInterrupts();