diff --git a/SConstruct b/SConstruct index 9faeb71..c382e2b 100644 --- a/SConstruct +++ b/SConstruct @@ -163,6 +163,7 @@ add_option( "release" , "release build" , 0 , True ) add_option( "static" , "fully static build" , 0 , False ) add_option( "static-libstdc++" , "statically link libstdc++" , 0 , False ) add_option( "lto", "enable link time optimizations (experimental, except with MSVC)" , 0 , True ) +add_option( "disable-declspec-thread", "don't use __declspec(thread) on Windows", 0, True) # base compile flags add_option( "64" , "whether to force 64 bit" , 0 , True , "force64" ) @@ -1194,6 +1195,51 @@ def doConfigure(myenv): if linux: AddToCCFLAGSIfSupported(myenv, "-fno-builtin-memcmp") + # When using msvc, check for support for __declspec(thread), unless we have been asked + # explicitly not to use it. For other compilers, see if __thread works. + if using_msvc(): + haveDeclSpecThread = False + if not has_option("disable-declspec-thread"): + def CheckDeclspecThread(context): + test_body = """ + __declspec( thread ) int tsp_int; + int main(int argc, char* argv[]) { + tsp_int = argc; + return 0; + } + """ + context.Message('Checking for __declspec(thread)... ') + ret = context.TryLink(textwrap.dedent(test_body), ".cpp") + context.Result(ret) + return ret + conf = Configure(myenv, help=False, custom_tests = { + 'CheckDeclspecThread' : CheckDeclspecThread, + }) + haveDeclSpecThread = conf.CheckDeclspecThread() + conf.Finish() + if haveDeclSpecThread: + myenv.Append(CPPDEFINES=['MONGO_HAVE___DECLSPEC_THREAD']) + else: + def CheckUUThread(context): + test_body = """ + __thread int tsp_int; + int main(int argc, char* argv[]) { + tsp_int = argc; + return 0; + } + """ + context.Message('Checking for __thread... ') + ret = context.TryLink(textwrap.dedent(test_body), ".cpp") + context.Result(ret) + return ret + conf = Configure(myenv, help=False, custom_tests = { + 'CheckUUThread' : CheckUUThread, + }) + haveUUThread = conf.CheckUUThread() + conf.Finish() + if haveUUThread: + myenv.Append(CPPDEFINES=['MONGO_HAVE___THREAD']) + conf = Configure(myenv) if use_system_version_of_library("pcre"): diff --git a/src/mongo/db/storage/record.cpp b/src/mongo/db/storage/record.cpp index 211ceaf..b3ecdf8 100644 --- a/src/mongo/db/storage/record.cpp +++ b/src/mongo/db/storage/record.cpp @@ -383,12 +383,12 @@ namespace mongo { // These need to be outside the ps namespace due to the way they are defined -#if defined(__linux__) && defined(__GNUC__) +#if defined(MONGO_HAVE___THREAD) __thread ps::PointerTable::Data _pointerTableData; ps::PointerTable::Data* ps::PointerTable::getData() { return &_pointerTableData; } -#elif defined(_WIN32) +#elif defined(MONGO_HAVE___DECLSPEC_THREAD) __declspec( thread ) ps::PointerTable::Data _pointerTableData; ps::PointerTable::Data* ps::PointerTable::getData() { return &_pointerTableData; diff --git a/src/mongo/util/concurrency/threadlocal.h b/src/mongo/util/concurrency/threadlocal.h index 4929833..a6f84ac 100644 --- a/src/mongo/util/concurrency/threadlocal.h +++ b/src/mongo/util/concurrency/threadlocal.h @@ -74,7 +74,7 @@ namespace mongo { a combination here, with the assumption that reset's are infrequent, so that get's are fast. */ -#if defined(_WIN32) || (defined(__GNUC__) && defined(__linux__)) +#if defined(MONGO_HAVE___THREAD) || defined(MONGO_HAVE___DECLSPEC_THREAD) template< class T > struct TSP { @@ -90,7 +90,7 @@ namespace mongo { } }; -# if defined(_WIN32) +# if defined(MONGO_HAVE___DECLSPEC_THREAD) # define TSP_DECLARE(T,p) extern TSP p; @@ -117,7 +117,7 @@ namespace mongo { TSP p; # endif -#elif defined(__APPLE__) +#elif defined(_POSIX_THREADS) && (_POSIX_THREADS >= 0) template< class T> struct TSP { pthread_key_t _key;