diff --git a/SConstruct b/SConstruct index a7c7fcade2c..be95d327aed 100644 --- a/SConstruct +++ b/SConstruct @@ -79,9 +79,10 @@ def add_option( name, help, nargs, contributesToVariantDir, help=help ) options[name] = { "help" : help , - "nargs" : nargs , + "nargs" : nargs , "contributesToVariantDir" : contributesToVariantDir , - "dest" : dest } + "dest" : dest, + "default": default } def get_option( name ): return GetOption( name ) @@ -121,6 +122,8 @@ def get_variant_dir(): continue if not o["contributesToVariantDir"]: continue + if get_option(o["dest"]) == o["default"]: + continue if o["nargs"] == 0: a.append( name ) @@ -199,7 +202,8 @@ add_option( "clang" , "use clang++ rather than g++ (experimental)" , 0 , True ) # debugging/profiling help -add_option( "tcmalloc" , "link against tcmalloc" , 0 , False ) +add_option( "allocator" , "allocator to use (tcmalloc or system)" , 1 , True, + default=(sys.platform.startswith('linux') and 'tcmalloc' or 'system') ) add_option( "gdbserver" , "build in gdb server support" , 0 , True ) add_option( "heapcheck", "link to heap-checking malloc-lib and look for memory leaks during tests" , 0 , False ) add_option( "gcov" , "compile with flags for gcov" , 0 , True ) @@ -207,6 +211,8 @@ add_option( "gcov" , "compile with flags for gcov" , 0 , True ) add_option("smokedbprefix", "prefix to dbpath et al. for smoke tests", 1 , False ) add_option("smokeauth", "run smoke tests with --auth", 0 , False ) +add_option( "use-system-tcmalloc", "use system version of tcmalloc library", 0, True ) + add_option( "use-system-pcre", "use system version of pcre library", 0, True ) add_option( "use-system-boost", "use system version of boost libraries", 0, True ) @@ -298,8 +304,8 @@ env = Environment( BUILD_DIR=variantDir, PYSYSPLATFORM=os.sys.platform, PCRE_VERSION='8.30', - CONFIGUREDIR = scons_data_dir + '/sconf_temp', - CONFIGURELOG = scons_data_dir + '/config.log' + CONFIGUREDIR = '#' + scons_data_dir + '/sconf_temp', + CONFIGURELOG = '#' + scons_data_dir + '/config.log' ) env['_LIBDEPS'] = '$_LIBDEPS_OBJS' @@ -826,9 +832,19 @@ def doConfigure(myenv): # 'tcmalloc' needs to be the last library linked. Please, add new libraries before this # point. - if has_option("tcmalloc") or has_option("heapcheck"): - if not conf.CheckLib("tcmalloc"): + if get_option('allocator') == 'tcmalloc': + if use_system_version_of_library('tcmalloc'): + if not conf.CheckLib("tcmalloc"): + Exit(1) + elif has_option("heapcheck"): + print ("--heapcheck does not work with the tcmalloc embedded in the mongodb source " + "tree. Use --use-system-tcmalloc.") Exit(1) + elif get_option('allocator') == 'system': + pass + else: + print "Invalid --allocator parameter: \"%s\"" % get_option('allocator') + Exit(1) if has_option("heapcheck"): if ( not debugBuild ) and ( not debugLogging ): diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 389a386aabe..181e89b3caf 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -31,6 +31,7 @@ env.StaticLibrary('foundation', 'util/time_support.cpp', ], LIBDEPS=['stacktrace', + '$BUILD_DIR/third_party/shim_allocator', '$BUILD_DIR/third_party/shim_boost']) env.StaticLibrary('stringutils', ['util/stringutils.cpp', 'util/base64.cpp',]) diff --git a/src/third_party/SConscript b/src/third_party/SConscript index 0b4bfb8455d..5a535710222 100644 --- a/src/third_party/SConscript +++ b/src/third_party/SConscript @@ -42,3 +42,10 @@ else: env.Append(CPPPATH='$BUILD_DIR/third_party/js-1.7') env.SConscript('js-1.7/SConscript') env.StaticLibrary('shim_spidermonkey', ['shim_spidermonkey.cpp'], LIBDEPS=['js-1.7/js']) + +if (GetOption("allocator") != "tcmalloc") or use_system_version_of_library("tcmalloc"): + env.StaticLibrary("shim_allocator", "shim_allocator.cpp") +else: + env.SConscript('gperftools-2.0/SConscript') + env.StaticLibrary('shim_allocator', 'shim_allocator.cpp', + LIBDEPS=['gperftools-2.0/tcmalloc_minimal']) diff --git a/src/third_party/gperftools-2.0/SConscript b/src/third_party/gperftools-2.0/SConscript new file mode 100644 index 00000000000..c599bae2b5f --- /dev/null +++ b/src/third_party/gperftools-2.0/SConscript @@ -0,0 +1,60 @@ +# -*- mode: python -*- + +Import("env") + +files = [ + 'src/base/dynamic_annotations.c', + 'src/base/spinlock_internal.cc', + 'src/base/logging.cc', + 'src/base/atomicops-internals-x86.cc', + 'src/base/sysinfo.cc', + 'src/base/spinlock.cc', + 'src/tcmalloc.cc', + 'src/malloc_hook.cc', + 'src/span.cc', + 'src/maybe_threads.cc', + 'src/internal_logging.cc', + 'src/symbolize.cc', + 'src/system-alloc.cc', + 'src/memfs_malloc.cc', + 'src/central_freelist.cc', + 'src/thread_cache.cc', + 'src/page_heap.cc', + 'src/common.cc', + 'src/static_vars.cc', + 'src/stack_trace_table.cc', + 'src/malloc_extension.cc', + 'src/sampler.cc', + 'src/stacktrace.cc' + ] + +__malloc_hook_fragment = ''' +#include +void* (* volatile __malloc_hook)(size_t, const void*) = 0; +''' + +def __checkMallocHookVolatile(check_context): + check_context.Message("Checking if __malloc_hook is declared volatile... ") + is_malloc_hook_volatile = check_context.TryCompile(__malloc_hook_fragment, '.cc') + check_context.Result(is_malloc_hook_volatile) + check_context.env.Append(CPPDEFINES=dict( + MALLOC_HOOK_MAYBE_VOLATILE=(is_malloc_hook_volatile and "volatile" or ""))) + +conf = Configure(env.Clone(), custom_tests=dict(CheckMallocHookVolatile=__checkMallocHookVolatile)) +conf.CheckMallocHookVolatile() +env = conf.Finish() + + +env.Append( CPPDEFINES=["NO_TCMALLOC_SAMPLES","NO_TCMALLOC_SAMPLES","NO_HEAP_CHECK"] ) +env.Prepend( CPPPATH=["src/"] ) + +def removeIfPresent(lst, item): + try: + lst.remove(item) + except ValueError: + pass + +for to_remove in ['-Werror', "-Wsign-compare","-Wall"]: + removeIfPresent(env['CCFLAGS'], to_remove) + +env.StaticLibrary('tcmalloc_minimal', files) diff --git a/src/third_party/gperftools-2.0/src/config-10gen-linux.h b/src/third_party/gperftools-2.0/src/config-10gen-linux.h index d893b32d07c..100f86adc36 100644 --- a/src/third_party/gperftools-2.0/src/config-10gen-linux.h +++ b/src/third_party/gperftools-2.0/src/config-10gen-linux.h @@ -190,9 +190,6 @@ */ #define LT_OBJDIR ".libs/" -/* Define to 'volatile' if __malloc_hook is declared volatile */ -#define MALLOC_HOOK_MAYBE_VOLATILE volatile - /* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* #undef NO_MINUS_C_MINUS_O */ diff --git a/src/third_party/shim_allocator.cpp b/src/third_party/shim_allocator.cpp new file mode 100644 index 00000000000..777ede8d4a0 --- /dev/null +++ b/src/third_party/shim_allocator.cpp @@ -0,0 +1,2 @@ +// This file intentionally blank. shim_allocator.cpp is part of the third_party/shim_allocator +// library, used to manage memory allocator selection (tcmalloc, libc, etc.).