From 7d138d47862a267342bfecf00d081b7c78ff81c8 Mon Sep 17 00:00:00 2001 From: Benjamin Smedberg Date: Wed, 28 Oct 2009 10:28:57 -0700 Subject: [PATCH] Make NS_IsMainThread faster on our major platforms. (Bug 521750) r=dbaron --- configure.in | 10 +++++++++- xpcom/base/nscore.h | 6 ++++++ xpcom/glue/nsThreadUtils.cpp | 25 +++++++++++++++++-------- xpcom/glue/nsThreadUtils.h | 18 ++++++++++++++++-- xpcom/threads/nsThreadManager.cpp | 9 +++++++++ 5 files changed, 57 insertions(+), 11 deletions(-) diff --git a/configure.in b/configure.in index 2cd2cd9ca62..4ac23878341 100644 --- a/configure.in +++ b/configure.in @@ -4160,7 +4160,15 @@ if test "$ac_cv_trouble_comparing_to_zero" = yes ; then AC_DEFINE(HAVE_CPP_TROUBLE_COMPARING_TO_ZERO) fi - +AC_CACHE_CHECK(for __thread keyword for TLS variables, + ac_cv_thread_keyword, + [AC_TRY_COMPILE([__thread bool tlsIsMainThread = false;], + [return tlsIsMainThread;], + ac_cv_thread_keyword=yes, + ac_cv_thread_keyword=no)]) +if test "$ac_cv_thread_keyword" = yes; then + AC_DEFINE(HAVE_THREAD_TLS_KEYWORD) +fi dnl End of C++ language/feature checks AC_LANG_C diff --git a/xpcom/base/nscore.h b/xpcom/base/nscore.h index 7febe0b73de..4e7f2d2dd3c 100644 --- a/xpcom/base/nscore.h +++ b/xpcom/base/nscore.h @@ -466,6 +466,12 @@ typedef PRUint32 nsrefcnt; #define XPCOM_GLUE_AVOID_NSPR #endif +#if defined(_MSC_VER) && !defined(WINCE) +#define NS_TLS __declspec(thread) +#elif defined(HAVE_THREAD_TLS_KEYWORD) +#define NS_TLS __thread +#endif + /** * Static type annotations, enforced when static-checking is enabled: * diff --git a/xpcom/glue/nsThreadUtils.cpp b/xpcom/glue/nsThreadUtils.cpp index 9023e47c0d3..89ba1671527 100644 --- a/xpcom/glue/nsThreadUtils.cpp +++ b/xpcom/glue/nsThreadUtils.cpp @@ -116,20 +116,29 @@ NS_GetMainThread(nsIThread **result) #endif } -NS_METHOD_(PRBool) -NS_IsMainThread() +#ifndef MOZILLA_INTERNAL_API +bool NS_IsMainThread() { PRBool result = PR_FALSE; -#ifdef MOZILLA_INTERNAL_API - nsThreadManager::get()->nsThreadManager::GetIsMainThread(&result); -#else nsCOMPtr mgr = - do_GetService(NS_THREADMANAGER_CONTRACTID); + do_GetService(NS_THREADMANAGER_CONTRACTID); if (mgr) mgr->GetIsMainThread(&result); -#endif - return result; + return bool(result); } +#elif !defined(NS_TLS) +bool NS_IsMainThread() +{ + PRBool result = PR_FALSE; + nsThreadManager::get()->nsThreadManager::GetIsMainThread(&result); + return bool(result); +} +#elif !defined(MOZ_ENABLE_LIBXUL) +bool NS_IsMainThread() +{ + return gTLSIsMainThread; +} +#endif NS_METHOD NS_DispatchToCurrentThread(nsIRunnable *event) diff --git a/xpcom/glue/nsThreadUtils.h b/xpcom/glue/nsThreadUtils.h index 200a9c90bb7..6c68268851a 100644 --- a/xpcom/glue/nsThreadUtils.h +++ b/xpcom/glue/nsThreadUtils.h @@ -98,14 +98,28 @@ NS_GetCurrentThread(nsIThread **result); extern NS_COM_GLUE NS_METHOD NS_GetMainThread(nsIThread **result); +#if defined(MOZILLA_INTERNAL_API) && defined(NS_TLS) +// This is defined in nsThreadManager.cpp and initialized to `true` for the +// main thread by nsThreadManager::Init. +extern NS_TLS bool gTLSIsMainThread; + +#ifdef MOZ_ENABLE_LIBXUL +inline bool NS_IsMainThread() +{ + return gTLSIsMainThread; +} +#else +NS_COM bool NS_IsMainThread(); +#endif +#else /** * Test to see if the current thread is the main thread. * * @returns PR_TRUE if the current thread is the main thread, and PR_FALSE * otherwise. */ -extern NS_COM_GLUE NS_METHOD_(PRBool) -NS_IsMainThread(); +extern NS_COM_GLUE bool NS_IsMainThread(); +#endif /** * Dispatch the given event to the current thread. diff --git a/xpcom/threads/nsThreadManager.cpp b/xpcom/threads/nsThreadManager.cpp index 2d363db0202..e322a6e784a 100644 --- a/xpcom/threads/nsThreadManager.cpp +++ b/xpcom/threads/nsThreadManager.cpp @@ -38,11 +38,16 @@ #include "nsThreadManager.h" #include "nsThread.h" +#include "nsThreadUtils.h" #include "nsIClassInfoImpl.h" #include "nsTArray.h" #include "nsAutoPtr.h" #include "nsAutoLock.h" +#ifdef NS_TLS +NS_TLS bool gTLSIsMainThread = false; +#endif + typedef nsTArray< nsRefPtr > nsThreadArray; //----------------------------------------------------------------------------- @@ -101,6 +106,10 @@ nsThreadManager::Init() // GetIsMainThread calls that occur post-Shutdown. mMainThread->GetPRThread(&mMainPRThread); +#ifdef NS_TLS + gTLSIsMainThread = true; +#endif + mInitialized = PR_TRUE; return NS_OK; }