From 46d3315ad7901099bd414740dbfbe6d27f33da9a Mon Sep 17 00:00:00 2001 From: Aliaksey Kandratsenka Date: Fri, 14 Jul 2023 02:19:21 -0400 Subject: [PATCH] amputate maybe_threads This facility allowed us to build tcmalloc without linking in actual -lpthread. Via weak symbols we checked at runtime if pthread functions are available and if not, special single-threaded stubs were used instead. Not always brining in pthread dependency helped performance of some programs or libraries which depended at runtime on whether threads are linked or not. Most notable of those are libstdc++ which uses non-atomic refcounting on single threaded programs. But such optional dependency on pthreads caused complications for nearly no benefit. One trouble was reported in github issue #1110. This days glibc/libstdc++ combo actually depends on sys/single_threaded.h facility. So bringing pthread at runtime is fine. Also modern glibc ships pthread symbols inside libc anyways and libpthread is empty. I also found that for whatever reason on BSDs and osx we already pulled in proper pthreads too. So we loose nothing and we get issue #1110 fixed. And we simplify everything. --- .gitignore | 1 - CMakeLists.txt | 27 +---- INSTALL | 2 +- Makefile.am | 44 ++------ configure.ac | 17 --- src/heap-checker.cc | 3 +- src/malloc_extension.cc | 1 - src/malloc_hook.cc | 1 - src/maybe_threads.cc | 144 -------------------------- src/maybe_threads.h | 59 ----------- src/profile-handler.cc | 11 +- src/static_vars.cc | 3 +- src/tests/low_level_alloc_unittest.cc | 2 - src/tests/maybe_threads_unittest.sh | 79 -------------- src/thread_cache.cc | 1 - src/thread_cache.h | 7 +- src/windows/port.h | 3 +- 17 files changed, 24 insertions(+), 381 deletions(-) delete mode 100644 src/maybe_threads.cc delete mode 100644 src/maybe_threads.h delete mode 100755 src/tests/maybe_threads_unittest.sh diff --git a/.gitignore b/.gitignore index 51c2f8d..4305609 100644 --- a/.gitignore +++ b/.gitignore @@ -77,7 +77,6 @@ /malloc_hook_test.exe /markidle_unittest /markidle_unittest.exe -/maybe_threads_unittest.sh /memalign_debug_unittest /memalign_unittest /missing diff --git a/CMakeLists.txt b/CMakeLists.txt index 32e6965..9fcda53 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -410,12 +410,6 @@ if(EXISTS /usr/sfw/lib/libstdc++.la) endif() endif() -check_cxx_source_compiles( - "#include - #include - int main() { pthread_t th; pthread_join(th, 0); return 0; }" - have_pthread_despite_asking_for) - check_variable_exists("program_invocation_name" HAVE_PROGRAM_INVOCATION_NAME) if(MINGW) @@ -572,10 +566,6 @@ if(MINGW OR MSVC) # (We do this via a #pragma for msvc, but need to do it here for mingw). target_link_libraries(sysinfo shlwapi) - if(have_pthread_despite_asking_for) - add_library(maybe_threads STATIC src/maybe_threads.cc) - set(maybe_threads_lib maybe_threads) - endif() else() set(SPINLOCK_INCLUDES src/base/spinlock.h src/base/spinlock_internal.h) @@ -588,8 +578,6 @@ else() set(TCMALLOC_CC "src/tcmalloc.cc") set(SYSTEM_ALLOC_CC "src/system-alloc.cc") - add_library(maybe_threads STATIC src/maybe_threads.cc) - set(maybe_threads_lib maybe_threads) endif() if(BUILD_TESTING) @@ -614,7 +602,7 @@ if(BUILD_TESTING) # By default, MallocHook takes stack traces for use by the heap-checker. # We don't need that functionality here, so we turn it off to reduce deps. target_compile_definitions(low_level_alloc_unittest PRIVATE NO_TCMALLOC_SAMPLES) - target_link_libraries(low_level_alloc_unittest spinlock sysinfo logging ${maybe_threads_lib}) + target_link_libraries(low_level_alloc_unittest spinlock sysinfo logging) add_test(low_level_alloc_unittest low_level_alloc_unittest) endif() @@ -745,7 +733,7 @@ add_library(tcmalloc_minimal_internal_object OBJECT ${libtcmalloc_minimal_intern # We #define NO_TCMALLOC_SAMPLES, since sampling is turned off for _minimal. target_compile_definitions(tcmalloc_minimal_internal_object PRIVATE NO_TCMALLOC_SAMPLES NO_HEAP_CHECK NDEBUG) add_library(tcmalloc_minimal_internal INTERFACE) -target_link_libraries(tcmalloc_minimal_internal INTERFACE ${LIBSPINLOCK} ${maybe_threads_lib}) +target_link_libraries(tcmalloc_minimal_internal INTERFACE ${LIBSPINLOCK}) target_sources(tcmalloc_minimal_internal INTERFACE $) set(libtcmalloc_minimal_la_SOURCES ${TCMALLOC_CC} ${TCMALLOC_MINIMAL_INCLUDES}) @@ -815,13 +803,6 @@ if(BUILD_TESTING) tcmalloc_minimal_large_heap_fragmentation_unittest PUBLIC tcmalloc_minimal) add_test(tcmalloc_minimal_large_heap_fragmentation_unittest tcmalloc_minimal_large_heap_fragmentation_unittest) - if(BUILD_SHARED_LIBS AND NOT MINGW) - add_custom_target(maybe_threads_unittest - COMMAND src/tests/maybe_threads_unittest.sh - VERBATIM) - add_test(maybe_threads_unittest maybe_threads_unittest) - endif() - if(MINGW OR MSVC) set(port_src src/windows/port.cc) endif() @@ -1064,7 +1045,7 @@ if(GPERFTOOLS_BUILD_HEAP_CHECKER OR GPERFTOOLS_BUILD_HEAP_PROFILER) set(libtcmalloc_la_SOURCES ${TCMALLOC_CC} ${TCMALLOC_INCLUDES}) set(libtcmalloc_la_DEFINE NDEBUG ${EMERGENCY_MALLOC_DEFINE}) - set(libtcmalloc_la_LIBADD tcmalloc_internal ${maybe_threads_lib} Threads::Threads) + set(libtcmalloc_la_LIBADD tcmalloc_internal Threads::Threads) if(GPERFTOOLS_BUILD_HEAP_CHECKER) # heap-checker-bcad is last, in hopes its global ctor will run first. # (Note this is added to libtcmalloc.la, not libtcmalloc_internal.la, @@ -1282,7 +1263,7 @@ if(GPERFTOOLS_BUILD_CPU_PROFILER) src/profile-handler.cc src/profiledata.cc ${CPU_PROFILER_INCLUDES}) - set(libprofiler_la_LIBADD stacktrace ${maybe_threads_lib} fake_stacktrace_scope) + set(libprofiler_la_LIBADD stacktrace fake_stacktrace_scope) add_library(profiler SHARED ${libprofiler_la_SOURCES}) target_link_libraries(profiler PRIVATE ${libprofiler_la_LIBADD}) set_target_properties(profiler PROPERTIES diff --git a/INSTALL b/INSTALL index af624e0..fcd0d25 100644 --- a/INSTALL +++ b/INSTALL @@ -249,7 +249,7 @@ above, by linking in libtcmalloc_minimal. libtcmalloc.so successfully builds, and the "advanced" tcmalloc functionality all works except for the leak-checker, which has Linux-specific code: - % make heap-profiler_unittest.sh maybe_threads_unittest.sh \ + % make heap-profiler_unittest.sh \ tcmalloc_unittest tcmalloc_both_unittest \ tcmalloc_large_unittest # THESE WORK % make -k heap-checker_unittest.sh \ diff --git a/Makefile.am b/Makefile.am index b6cea8c..0ecddd7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -168,10 +168,6 @@ libsysinfo_la_SOURCES = src/base/sysinfo.cc \ $(SYSINFO_INCLUDES) libsysinfo_la_LIBADD = $(NANOSLEEP_LIBS) -noinst_LTLIBRARIES += libmaybe_threads.la -# .cc is conditionally added below -libmaybe_threads_la_SOURCES = src/maybe_threads.h - # For MinGW, we use also have to use libwindows Luckily, we need the # windows.a library in exactly the same place we need spinlock.a # (pretty much everywhere), so we can use the same variable name for @@ -227,10 +223,6 @@ libsysinfo_la_LIBADD += -lshlwapi # patch_functions.cc #includes tcmalloc.cc, so no need to link it in. TCMALLOC_CC = -# windows has its own system for threads and system memory allocation. -if HAVE_PTHREAD_DESPITE_ASKING_FOR -libmaybe_threads_la_SOURCES += src/maybe_threads.cc -endif SYSTEM_ALLOC_CC = else !MINGW SPINLOCK_INCLUDES = src/base/spinlock.h \ @@ -245,7 +237,6 @@ libspinlock_la_LIBADD = $(NANOSLEEP_LIBS) LIBSPINLOCK = libspinlock.la libsysinfo.la liblogging.la TCMALLOC_CC = src/tcmalloc.cc -libmaybe_threads_la_SOURCES += src/maybe_threads.cc SYSTEM_ALLOC_CC = src/system-alloc.cc endif !MINGW @@ -276,7 +267,7 @@ low_level_alloc_unittest_SOURCES = src/base/low_level_alloc.cc \ # By default, MallocHook takes stack traces for use by the heap-checker. # We don't need that functionality here, so we turn it off to reduce deps. low_level_alloc_unittest_CXXFLAGS = -DNO_TCMALLOC_SAMPLES -low_level_alloc_unittest_LDADD = $(LIBSPINLOCK) libmaybe_threads.la +low_level_alloc_unittest_LDADD = $(LIBSPINLOCK) ### ------- stack trace @@ -439,7 +430,7 @@ libtcmalloc_minimal_internal_la_CXXFLAGS = -DNO_TCMALLOC_SAMPLES \ -DNDEBUG \ $(AM_CXXFLAGS) libtcmalloc_minimal_internal_la_LDFLAGS = $(AM_LDFLAGS) -libtcmalloc_minimal_internal_la_LIBADD = $(LIBSPINLOCK) libmaybe_threads.la +libtcmalloc_minimal_internal_la_LIBADD = $(LIBSPINLOCK) lib_LTLIBRARIES += libtcmalloc_minimal.la WINDOWS_PROJECTS += vsprojects/libtcmalloc_minimal/libtcmalloc_minimal.vcxproj @@ -474,11 +465,9 @@ LIBS_TO_WEAKEN += libtcmalloc_minimal.la ## src/malloc_hook_mmap_linux.h \ ## src/malloc_hook_mmap_freebsd.h \ ## src/base/basictypes.h \ -## src/maybe_threads.h ## malloc_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \ ## src/malloc_hook.cc \ ## src/malloc_extension.cc \ -## $(MAYBE_THREADS_CC) \ ## $(MALLOC_UNITTEST_INCLUDES) ## malloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) ## malloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS) @@ -512,7 +501,7 @@ tcm_min_asserts_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \ tcm_min_asserts_unittest_CXXFLAGS = -DNO_TCMALLOC_SAMPLES -DNO_HEAP_CHECK \ $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) tcm_min_asserts_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS) -tcm_min_asserts_unittest_LDADD = $(LIBSPINLOCK) libmaybe_threads.la \ +tcm_min_asserts_unittest_LDADD = $(LIBSPINLOCK) \ liblogging.la $(PTHREAD_LIBS) TESTS += tcmalloc_minimal_large_unittest @@ -528,27 +517,6 @@ tcmalloc_minimal_large_heap_fragmentation_unittest_CXXFLAGS = $(PTHREAD_CFLAGS) tcmalloc_minimal_large_heap_fragmentation_unittest_LDFLAGS = $(PTHREAD_CFLAGS) $(TCMALLOC_FLAGS) tcmalloc_minimal_large_heap_fragmentation_unittest_LDADD = $(LIBTCMALLOC_MINIMAL) $(PTHREAD_LIBS) -# This tests it works to LD_PRELOAD libtcmalloc (tests maybe_threads.cc) -# In theory this should work under mingw, but mingw has trouble running -# shell scripts that end in .exe. And it doesn't seem to build shared -# libraries anyway (so can't be LD_PRELOADed) -- in fact, anybody who -# chooses not to build shared libraries won't be able to run this test. -# TODO(csilvers): figure out how to nix ".exe" or otherwise work under mingw -if !MINGW -if !ENABLE_STATIC -TESTS += maybe_threads_unittest.sh$(EXEEXT) -maybe_threads_unittest_sh_SOURCES = src/tests/maybe_threads_unittest.sh -noinst_SCRIPTS += $(maybe_threads_unittest_sh_SOURCES) -# This script preloads libtcmalloc, and calls two other binaries as well -# TODO(csilvers): replace by 'if ! cmp $^ $@ >/dev/null 2>&; then ...; fi' -maybe_threads_unittest.sh$(EXEEXT): $(top_srcdir)/$(maybe_threads_unittest_sh_SOURCES) \ - $(LIBTCMALLOC_MINIMAL) \ - low_level_alloc_unittest - rm -f $@ - cp -p $(top_srcdir)/$(maybe_threads_unittest_sh_SOURCES) $@ -endif !ENABLE_STATIC -endif !MINGW - # These all tests components of tcmalloc_minimal TESTS += addressmap_unittest @@ -934,7 +902,7 @@ libtcmalloc_la_SOURCES = $(TCMALLOC_CC) $(TCMALLOC_INCLUDES) \ libtcmalloc_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG $(AM_CXXFLAGS) \ $(MAYBE_NO_HEAP_CHECK) $(EMERGENCY_MALLOC_DEFINE) libtcmalloc_la_LDFLAGS = $(PTHREAD_CFLAGS) -version-info @TCMALLOC_SO_VERSION@ -libtcmalloc_la_LIBADD = libtcmalloc_internal.la libmaybe_threads.la $(PTHREAD_LIBS) +libtcmalloc_la_LIBADD = libtcmalloc_internal.la $(PTHREAD_LIBS) # same as above with without -DNDEBUG noinst_LTLIBRARIES += libtcmalloc_internal_with_asserts.la @@ -950,7 +918,7 @@ libtcmalloc_with_asserts_la_SOURCES = $(libtcmalloc_la_SOURCES) libtcmalloc_with_asserts_la_CXXFLAGS = $(PTHREAD_CFLAGS) $(AM_CXXFLAGS) \ $(MAYBE_NO_HEAP_CHECK) $(EMERGENCY_MALLOC_DEFINE) libtcmalloc_with_asserts_la_LDFLAGS = $(PTHREAD_CFLAGS) -libtcmalloc_with_asserts_la_LIBADD = libtcmalloc_internal_with_asserts.la libmaybe_threads.la $(PTHREAD_LIBS) +libtcmalloc_with_asserts_la_LIBADD = libtcmalloc_internal_with_asserts.la $(PTHREAD_LIBS) LIBTCMALLOC = libtcmalloc.la @@ -1270,7 +1238,7 @@ libprofiler_la_SOURCES = src/profiler.cc \ src/profile-handler.cc \ src/profiledata.cc \ $(CPU_PROFILER_INCLUDES) -libprofiler_la_LIBADD = libstacktrace.la libmaybe_threads.la libfake_stacktrace_scope.la +libprofiler_la_LIBADD = libstacktrace.la libfake_stacktrace_scope.la # We have to include ProfileData for profiledata_unittest CPU_PROFILER_SYMBOLS = '(ProfilerStart|ProfilerStartWithOptions|ProfilerStop|ProfilerFlush|ProfilerEnable|ProfilerDisable|ProfilingIsEnabledForAllThreads|ProfilerRegisterThread|ProfilerGetCurrentState|ProfilerState|ProfileData|ProfileHandler|ProfilerGetStackTrace)' libprofiler_la_LDFLAGS = -export-symbols-regex $(CPU_PROFILER_SYMBOLS) \ diff --git a/configure.ac b/configure.ac index c9bc43f..62e3ad6 100644 --- a/configure.ac +++ b/configure.ac @@ -518,23 +518,6 @@ AC_SUBST(LIBSTDCXX_LA_LINKER_FLAG) # In fact, a lot of the code in this directory depends on pthreads AX_PTHREAD -AC_MSG_CHECKING([whether pthread symbols are available in C++ without including pthread.h]) -acx_pthread_despite_asking_for=no -AC_LINK_IFELSE( - [AC_LANG_PROGRAM([ - #include - #include - ],[ - pthread_t th; pthread_join(th, 0); - ])],[ - acx_pthread_despite_asking_for=yes - AC_DEFINE(HAVE_PTHREAD_DESPITE_ASKING_FOR, 1, [defined to 1 if pthread symbols are exposed even without include pthread.h]) - AC_DEFINE(HAVE_PTHREAD, 1, []) - ]) -AC_MSG_RESULT([$acx_pthread_despite_asking_for]) - -AM_CONDITIONAL(HAVE_PTHREAD_DESPITE_ASKING_FOR, test x"$acx_pthread_despite_asking_for" = xyes) - # Figure out where libc has program_invocation_name AC_PROGRAM_INVOCATION_NAME diff --git a/src/heap-checker.cc b/src/heap-checker.cc index ebaca57..9c27da0 100644 --- a/src/heap-checker.cc +++ b/src/heap-checker.cc @@ -84,7 +84,6 @@ #include "base/sysinfo.h" #include "heap-profile-table.h" #include "malloc_hook-inl.h" -#include "maybe_threads.h" #include "memory_region_map.h" #include "safe_strerror.h" @@ -555,7 +554,7 @@ inline void set_thread_disable_counter(int value) { class InitThreadDisableCounter { public: InitThreadDisableCounter() { - perftools_pthread_key_create(&thread_disable_counter_key, NULL); + pthread_key_create(&thread_disable_counter_key, NULL); // Set up the main thread's value, which we have a special variable for. void* p = (void*)(intptr_t)main_thread_counter; // store the counter directly perftools_pthread_setspecific(thread_disable_counter_key, p); diff --git a/src/malloc_extension.cc b/src/malloc_extension.cc index 68cb98a..98f5177 100644 --- a/src/malloc_extension.cc +++ b/src/malloc_extension.cc @@ -50,7 +50,6 @@ #endif #include "gperftools/malloc_extension.h" #include "gperftools/malloc_extension_c.h" -#include "maybe_threads.h" #include "base/googleinit.h" using std::string; diff --git a/src/malloc_hook.cc b/src/malloc_hook.cc index 6c2982e..65bcf0b 100644 --- a/src/malloc_hook.cc +++ b/src/malloc_hook.cc @@ -50,7 +50,6 @@ #include "base/logging.h" #include "base/spinlock.h" #include "maybe_emergency_malloc.h" -#include "maybe_threads.h" #include "malloc_hook-inl.h" #include diff --git a/src/maybe_threads.cc b/src/maybe_threads.cc deleted file mode 100644 index 8906c53..0000000 --- a/src/maybe_threads.cc +++ /dev/null @@ -1,144 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- -// Copyright (c) 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Paul Menage -// -// Some wrappers for pthread functions so that we can be LD_PRELOADed -// against non-pthreads apps. -// -// This module will behave very strangely if some pthreads functions -// exist and others don't. - -#include "config.h" -#include -#include // for memcmp -#include // for __isthreaded on FreeBSD -// We don't actually need strings. But including this header seems to -// stop the compiler trying to short-circuit our pthreads existence -// tests and claiming that the address of a function is always -// non-zero. I have no idea why ... -#include -#include "maybe_threads.h" -#include "base/basictypes.h" -#include "base/logging.h" - -// __THROW is defined in glibc systems. It means, counter-intuitively, -// "This function will never throw an exception." It's an optional -// optimization tool, but we may need to use it to match glibc prototypes. -#ifndef __THROW // I guess we're not on a glibc system -# define __THROW // __THROW is just an optimization, so ok to make it "" -#endif - -// These are the methods we're going to conditionally include. -extern "C" { - int pthread_key_create (pthread_key_t*, void (*)(void*)) - __THROW ATTRIBUTE_WEAK; - int pthread_key_delete (pthread_key_t) - __THROW ATTRIBUTE_WEAK; - void *pthread_getspecific(pthread_key_t) - __THROW ATTRIBUTE_WEAK; - int pthread_setspecific(pthread_key_t, const void*) - __THROW ATTRIBUTE_WEAK; - int pthread_once(pthread_once_t *, void (*)(void)) - ATTRIBUTE_WEAK; -#ifdef HAVE_FORK - int pthread_atfork(void (*__prepare) (void), - void (*__parent) (void), - void (*__child) (void)) - __THROW ATTRIBUTE_WEAK; -#endif -} - -#define MAX_PERTHREAD_VALS 16 -static void *perftools_pthread_specific_vals[MAX_PERTHREAD_VALS]; -static int next_key; - -// NOTE: it's similar to bitcast defined in basic_types.h with -// exception of ignoring sizes mismatch -template -static T2 memcpy_cast(const T1 &input) { - T2 output; - size_t s = sizeof(input); - if (sizeof(output) < s) { - s = sizeof(output); - } - memcpy(&output, &input, s); - return output; -} - -int perftools_pthread_key_create(pthread_key_t *key, - void (*destr_function) (void *)) { - if (pthread_key_create) { - return pthread_key_create(key, destr_function); - } else { - assert(next_key < MAX_PERTHREAD_VALS); - *key = memcpy_cast(next_key++); - return 0; - } -} - -int perftools_pthread_key_delete(pthread_key_t key) { - if (pthread_key_delete) { - return pthread_key_delete(key); - } else { - return 0; - } -} - -void *perftools_pthread_getspecific(pthread_key_t key) { - if (pthread_getspecific) { - return pthread_getspecific(key); - } else { - return perftools_pthread_specific_vals[memcpy_cast(key)]; - } -} - -int perftools_pthread_setspecific(pthread_key_t key, void *val) { - if (pthread_setspecific) { - return pthread_setspecific(key, val); - } else { - perftools_pthread_specific_vals[memcpy_cast(key)] = val; - return 0; - } -} - -#ifdef HAVE_FORK - -void perftools_pthread_atfork(void (*before)(), - void (*parent_after)(), - void (*child_after)()) { - if (pthread_atfork) { - int rv = pthread_atfork(before, parent_after, child_after); - CHECK(rv == 0); - } -} - -#endif diff --git a/src/maybe_threads.h b/src/maybe_threads.h deleted file mode 100644 index d577bea..0000000 --- a/src/maybe_threads.h +++ /dev/null @@ -1,59 +0,0 @@ -// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- -// Copyright (c) 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Paul Menage - -//------------------------------------------------------------------- -// Some wrappers for pthread functions so that we can be LD_PRELOADed -// against non-pthreads apps. -//------------------------------------------------------------------- - -#ifndef GOOGLE_MAYBE_THREADS_H_ -#define GOOGLE_MAYBE_THREADS_H_ - -#ifdef HAVE_PTHREAD -#include -#endif - -int perftools_pthread_key_create(pthread_key_t *key, - void (*destr_function) (void *)); -int perftools_pthread_key_delete(pthread_key_t key); -void *perftools_pthread_getspecific(pthread_key_t key); -int perftools_pthread_setspecific(pthread_key_t key, void *val); - -// Our wrapper for pthread_atfork. Does _nothing_ when there are no -// threads. See static_vars.cc:SetupAtForkLocksHandler for only user -// of this. -void perftools_pthread_atfork(void (*before)(), - void (*parent_after)(), - void (*child_after)()); - -#endif /* GOOGLE_MAYBE_THREADS_H_ */ diff --git a/src/profile-handler.cc b/src/profile-handler.cc index 6518cc3..bf39ca5 100644 --- a/src/profile-handler.cc +++ b/src/profile-handler.cc @@ -47,22 +47,19 @@ #include #if HAVE_LINUX_SIGEV_THREAD_ID +#include // for timer_{create,settime} and associated typedefs & constants #include // for sigevent #include // for SYS_gettid #include - -// for perftools_pthread_key_create -#include "maybe_threads.h" #endif #include "base/dynamic_annotations.h" #include "base/googleinit.h" #include "base/logging.h" #include "base/spinlock.h" -#include "maybe_threads.h" // Some Linux systems don't have sigev_notify_thread_id defined in // signal.h (despite having SIGEV_THREAD_ID defined) and also lack @@ -268,7 +265,7 @@ extern "C" { } static void CreateThreadTimerKey(pthread_key_t *pkey) { - int rv = perftools_pthread_key_create(pkey, ThreadTimerDestructor); + int rv = pthread_key_create(pkey, ThreadTimerDestructor); if (rv) { RAW_LOG(FATAL, "aborting due to pthread_key_create error: %s", strerror(rv)); } @@ -294,7 +291,7 @@ static void StartLinuxThreadTimer(int timer_type, int signal_number, } timer_id_holder *holder = new timer_id_holder(timerid); - rv = perftools_pthread_setspecific(timer_key, holder); + rv = pthread_setspecific(timer_key, holder); if (rv) { RAW_LOG(FATAL, "aborting due to pthread_setspecific error: %s", strerror(rv)); } @@ -393,7 +390,7 @@ ProfileHandler::~ProfileHandler() { Reset(); #ifdef HAVE_LINUX_SIGEV_THREAD_ID if (per_thread_timer_enabled_) { - perftools_pthread_key_delete(thread_timer_key); + pthread_key_delete(thread_timer_key); } #endif } diff --git a/src/static_vars.cc b/src/static_vars.cc index 7da32cb..d0798d2 100644 --- a/src/static_vars.cc +++ b/src/static_vars.cc @@ -43,7 +43,6 @@ #include "sampler.h" // for Sampler #include "getenv_safe.h" // TCMallocGetenvSafe #include "base/googleinit.h" -#include "maybe_threads.h" namespace tcmalloc { @@ -137,7 +136,7 @@ void Static::InitLateMaybeRecursive() { // be less fortunate and allow some early app constructors to run // before malloc is ever called. - perftools_pthread_atfork( + pthread_atfork( CentralCacheLockAll, // parent calls before fork CentralCacheUnlockAll, // parent calls after fork CentralCacheUnlockAll); // child calls after fork diff --git a/src/tests/low_level_alloc_unittest.cc b/src/tests/low_level_alloc_unittest.cc index 0474441..02c22d9 100644 --- a/src/tests/low_level_alloc_unittest.cc +++ b/src/tests/low_level_alloc_unittest.cc @@ -163,8 +163,6 @@ static void FreeHook(const void *p) { } int main(int argc, char *argv[]) { - // This is needed by maybe_threads_unittest.sh, which parses argv[0] - // to figure out what directory low_level_alloc_unittest is in. if (argc != 1) { fprintf(stderr, "USAGE: %s\n", argv[0]); return 1; diff --git a/src/tests/maybe_threads_unittest.sh b/src/tests/maybe_threads_unittest.sh deleted file mode 100755 index 77b3b78..0000000 --- a/src/tests/maybe_threads_unittest.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2007, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# --- -# Author: Craig Silverstein -# -# maybe_threads.cc was written to allow LD_PRELOAD=libtcmalloc.so to -# work even on binaries that were not linked with pthreads. This -# unittest tests that, by running low_level_alloc_unittest with an -# LD_PRELOAD. (low_level_alloc_unittest was chosen because it doesn't -# link in tcmalloc.) -# -# We assume all the .so files are in the same directory as both -# addressmap_unittest and profiler1_unittest. The reason we need -# profiler1_unittest is because it's instrumented to show the directory -# it's "really" in when run without any args. In practice this will either -# be BINDIR, or, when using libtool, BINDIR/.lib. - -# We expect BINDIR to be set in the environment. -# If not, we set them to some reasonable values. -BINDIR="${BINDIR:-.}" - -if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then - echo "USAGE: $0 [unittest dir]" - echo " By default, unittest_dir=$BINDIR" - exit 1 -fi - -UNITTEST_DIR=${1:-$BINDIR} - -# Figure out the "real" unittest directory. Also holds the .so files. -UNITTEST_DIR=`$UNITTEST_DIR/low_level_alloc_unittest --help 2>&1 \ - | awk '{print $2; exit;}' \ - | xargs dirname` - -# Figure out where libtcmalloc lives. It should be in UNITTEST_DIR, -# but with libtool it might be in a subdir. -if [ -r "$UNITTEST_DIR/libtcmalloc_minimal.so" ]; then - LIB_PATH="$UNITTEST_DIR/libtcmalloc_minimal.so" -elif [ -r "$UNITTEST_DIR/.libs/libtcmalloc_minimal.so" ]; then - LIB_PATH="$UNITTEST_DIR/.libs/libtcmalloc_minimal.so" -elif [ -r "$UNITTEST_DIR/libtcmalloc_minimal.dylib" ]; then # for os x - LIB_PATH="$UNITTEST_DIR/libtcmalloc_minimal.dylib" -elif [ -r "$UNITTEST_DIR/.libs/libtcmalloc_minimal.dylib" ]; then - LIB_PATH="$UNITTEST_DIR/.libs/libtcmalloc_minimal.dylib" -else - echo "Cannot run $0: cannot find libtcmalloc_minimal.so" - exit 2 -fi - -LD_PRELOAD="$LIB_PATH" $UNITTEST_DIR/low_level_alloc_unittest diff --git a/src/thread_cache.cc b/src/thread_cache.cc index b99b37f..8c1b279 100644 --- a/src/thread_cache.cc +++ b/src/thread_cache.cc @@ -40,7 +40,6 @@ #include "base/spinlock.h" // for SpinLockHolder #include "getenv_safe.h" // for TCMallocGetenvSafe #include "central_freelist.h" // for CentralFreeListPadded -#include "maybe_threads.h" using std::min; using std::max; diff --git a/src/thread_cache.h b/src/thread_cache.h index f8be152..780de59 100644 --- a/src/thread_cache.h +++ b/src/thread_cache.h @@ -46,7 +46,6 @@ #include "base/commandlineflags.h" #include "common.h" #include "linked_list.h" -#include "maybe_threads.h" #include "page_heap_allocator.h" #include "sampler.h" #include "static_vars.h" @@ -60,6 +59,12 @@ DECLARE_int64(tcmalloc_sample_parameter); +#ifndef HAVE_PERFTOOLS_PTHREAD_KEYS +#define perftools_pthread_getspecific pthread_getspecific +#define perftools_pthread_setspecific pthread_setspecific +#define perftools_pthread_key_create pthread_key_create +#endif + namespace tcmalloc { //------------------------------------------------------------------- diff --git a/src/windows/port.h b/src/windows/port.h index 3666a4d..bdd7cd0 100644 --- a/src/windows/port.h +++ b/src/windows/port.h @@ -130,8 +130,7 @@ inline bool pthread_equal(pthread_t left, pthread_t right) { * we therefore shouldn't be #including directly. This hack keeps us from * doing so. TODO(csilvers): do something more principled. */ -#define GOOGLE_MAYBE_THREADS_H_ 1 -/* This replaces maybe_threads.{h,cc} */ +#define HAVE_PERFTOOLS_PTHREAD_KEYS EXTERN_C pthread_key_t PthreadKeyCreate(void (*destr_fn)(void*)); /* port.cc */